Skip to main content
Associate
Sep 3, 2025 3:49 AM UTC
Solved

stm32f411 as USB speaker: not able to respond to URB_ISOCHRONOUS IN

I'm a USB newbie and am trying to use the STM32F411CEU6 as a USB mic. I'm currently using FreeRTOS (cmsisV1) and the Cubemax USB library. My device currently enumerates normally, but when the host sends a URB_ISOCHRONOUS_IN request, my MCU won't handle it properly (according to SWD and serial port debugging, I found that the MCU won't even enter the OTG_FS_IRQHandler interrupt when the host sends this request). This has been bothering me for a long time. Here are my descriptors and some configuration code:

__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[] __ALIGN_END =
{
 /* Configuration Descriptor Head */
 0x09, // bLength
 0x02, // bDescriptorType = CONFIGURATION
 0x6D, 0x00, // wTotalLength = 109 bytes
 0x02, // bNumInterfaces = 2 (Audio Control + Audio Streaming)
 0x01, // bConfigurationValue
 0x00, // iConfiguration
 0x80, // bmAttributes: Bus powered
 0x32, // bMaxPower: 100mA

 /* -------- Audio Control Interface (Interface 0) -------- */
 0x09, // bLength
 0x04, // bDescriptorType = INTERFACE
 0x00, // bInterfaceNumber = 0
 0x00, // bAlternateSetting
 0x00, // bNumEndpoints
 0x01, // bInterfaceClass = AUDIO
 0x01, // bInterfaceSubClass = AUDIOCONTROL
 0x00, // bInterfaceProtocol
 0x00, // iInterface

 /* Class-Specific AC Interface Header Descriptor */
 0x09, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x01, // bDescriptorSubtype = HEADER
 0x00, 0x01, // bcdADC = 1.00
 0x27, 0x00, // wTotalLength = 30 bytes (AC descriptors)
 0x01, // bInCollection
 0x01, // baInterfaceNr(1) = 1 (AS interface)

 /* Input Terminal Descriptor (Microphone) */
 0x0C, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x02, // bDescriptorSubtype = INPUT_TERMINAL
 0x01, // bTerminalID
 0x01, 0x02, // wTerminalType = Microphone (0x0201)
 0x00, // bAssocTerminal
 0x01, // bNrChannels = 1 (Mono)
 0x00, 0x00, // wChannelConfig = Mono (no spatial config)
 0x00, // iChannelNames
 0x00, // iTerminal

 /* Feature Unit Descriptor */
 0x09, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x06, // bDescriptorSubtype = FEATURE_UNIT
 0x02, // bUnitID
 0x01, // bSourceID (Input Terminal = 1)
 0x01, // bControlSize = 1 byte per channel
 0x03, // bmaControls(0): Mute + volum Master channel
 0x00, // bmaControls(1): none for channel 1
 0x00, // iFeature

 /* Output Terminal Descriptor (USB Streaming) */
 0x09, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x03, // bDescriptorSubtype = OUTPUT_TERMINAL
 0x03, // bTerminalID
 0x01, 0x01, // wTerminalType = USB Streaming (0x0101)
 0x00, // bAssocTerminal
 0x01, // bSourceID (Feature Unit = 2)
 0x00, // iTerminal

 /* -------- Audio Streaming Interface (Interface 1) -------- */

 /* AS Interface Descriptor (Alt 0 - Zero Bandwidth) */
 0x09, // bLength
 0x04, // bDescriptorType = INTERFACE
 0x01, // bInterfaceNumber = 1
 0x00, // bAlternateSetting = 0
 0x00, // bNumEndpoints = 0
 0x01, // bInterfaceClass = AUDIO
 0x02, // bInterfaceSubClass = AUDIOSTREAMING
 0x00, // bInterfaceProtocol
 0x00, // iInterface

 /* AS Interface Descriptor (Alt 1 - Operational) */
 0x09, // bLength
 0x04, // bDescriptorType = INTERFACE
 0x01, // bInterfaceNumber = 1
 0x01, // bAlternateSetting = 1
 0x01, // bNumEndpoints = 1 (Iso IN)
 0x01, // bInterfaceClass = AUDIO
 0x02, // bInterfaceSubClass = AUDIOSTREAMING
 0x00, // bInterfaceProtocol
 0x00, // iInterface

 /* Class-Specific AS General Descriptor */
 0x07, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x01, // bDescriptorSubtype = AS_GENERAL
 0x03, // bTerminalLink (Output Terminal ID = 3)
 0x01, // bDelay
 0x01, 0x00, // wFormatTag = PCM

 /* Type I Format Type Descriptor */
 0x0B, // bLength
 0x24, // bDescriptorType = CS_INTERFACE
 0x02, // bDescriptorSubtype = FORMAT_TYPE
 0x01, // bFormatType = FORMAT_TYPE_I
 0x01, // bNrChannels = 1
 0x02, // bSubframeSize = 2 bytes per sample
 0x10, // bBitResolution = 16 bits
 0x01, // bSamFreqType = 1 (Discrete Sampling Frequency)
 0x80, 0xBB, 0x00, // tSamFreq[1] = 48000 Hz (0x00BB80)

 /* Standard Endpoint Descriptor (Isochronous IN Audio Data Endpoint) */
 0x09, // bLength
 0x05, // bDescriptorType = ENDPOINT
 0x81, // bEndpointAddress = IN endpoint 1
 0x09, // bmAttributes = Isochronous, asynchronous
 0x60, 0x00, // wMaxPacketSize = 96 bytes (48kHz x 2 bytes x 1 ch / 1ms)
 0x01, // bInterval = 1 (1 ms)
 0x00, // bRefresh
 0x00, // bSynchAddress

 /* Class-Specific Isochronous Audio Data Endpoint Descriptor */
 0x07, // bLength
 0x25, // bDescriptorType = CS_ENDPOINT
 0x01, // bDescriptorSubtype = EP_GENERAL
 0x00, // bmAttributes
 0x00, // bLockDelayUnits
 0x00, 0x00 // wLockDelay
};

Init Part:

static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
 USBD_AUDIO_HandleTypeDef *haudio;

 /* Open EP IN for MIC */
 USBD_LL_OpenEP(pdev, AUDIO_IN_EP, USBD_EP_TYPE_ISOC, AUDIO_IN_PACKET);
 pdev->ep_in[AUDIO_IN_EP & 0xFU].is_used = 1U;

 /* Allocate Audio structure */
 pdev->pClassData = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef));
 if (pdev->pClassData == NULL)
 {
 return USBD_FAIL;
 }
 /* Binding Class_func */
 haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData;
 haudio->alt_setting = 1U;
 haudio->offset = AUDIO_OFFSET_UNKNOWN;
 haudio->wr_ptr = 0U;
 haudio->rd_ptr = 0U;
 haudio->rd_enable = 1U;

 /* Initialize the Audio input (MIC) Hardware layer */
 if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[0])->Init(AUDIO_IN_FREQ,		/* Actually is AUDIO_Init_FS() */
 24U, /* 24bit */
 1U) != 0)
 {
 return USBD_FAIL;
 }

 /* Prepare IN endpoint for first packet */
 USBD_LL_Transmit(pdev, AUDIO_IN_EP, haudio->buffer, AUDIO_IN_PACKET);

 return USBD_OK;
}
static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
 USBD_SetupReqTypedef *req)
{
 USBD_AUDIO_HandleTypeDef *haudio;
 uint16_t len;
 uint8_t *pbuf;
 uint16_t status_info = 0U;
 uint8_t ret = USBD_OK;

 haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;

 switch (req->bmRequest & USB_REQ_TYPE_MASK)
 {
 case USB_REQ_TYPE_CLASS:
 switch (req->bRequest)
 {
 case AUDIO_REQ_GET_CUR:
 AUDIO_REQ_GetCurrent(pdev, req);
 break;

 case AUDIO_REQ_SET_CUR:
 AUDIO_REQ_SetCurrent(pdev, req);
 break;

 case AUDIO_REQ_GET_MIN:
 {
 int16_t vol_min = 0x0000;
 USBD_CtlSendData(pdev, (uint8_t *)&vol_min, sizeof(vol_min));
 break;
 }

 case AUDIO_REQ_GET_MAX:
 {
 int16_t vol_max = 0x6400;
 USBD_CtlSendData(pdev, (uint8_t *)&vol_max, sizeof(vol_max));
 break;
 }

 case AUDIO_REQ_GET_RES:
 {
 int16_t vol_res = 0x0100;
 USBD_CtlSendData(pdev, (uint8_t *)&vol_res, sizeof(vol_res));
 break;
 }

 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }
 break;

 case USB_REQ_TYPE_STANDARD:
 switch (req->bRequest)
 {
 case USB_REQ_GET_STATUS:
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;

 case USB_REQ_GET_DESCRIPTOR:
 if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
 {
 pbuf = USBD_AUDIO_CfgDesc + 18;
 len = MIN(USB_AUDIO_DESC_SIZ, req->wLength);
 USBD_CtlSendData(pdev, pbuf, len);
 }
 break;

 case USB_REQ_GET_INTERFACE:
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 USBD_CtlSendData(pdev, (uint8_t *)(void *)&haudio->alt_setting, 1U);
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;

 case USB_REQ_SET_INTERFACE:
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 uint8_t alt = (uint8_t)(req->wValue);

 haudio->alt_setting = alt;

 if (alt == 1)
 {
 USBD_LL_OpenEP(pdev,
 AUDIO_IN_EP,
 USBD_EP_TYPE_ISOC,
 AUDIO_IN_PACKET);
 pdev->ep_in[AUDIO_IN_EP & 0xFU].is_used = 1U;

 USBD_LL_Transmit(pdev,
 AUDIO_IN_EP,
 (uint8_t *)i2s_dma_buf,
 AUDIO_IN_PACKET);
 }
 else if (alt == 0)
 {
 USBD_LL_CloseEP(pdev, AUDIO_IN_EP);
 pdev->ep_in[AUDIO_IN_EP & 0xFU].is_used = 0U;
 }
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;

 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }
 break;

 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }

 return ret;
}

WireShark result:

Pete_Griffin_0-1756871265062.pngPete_Griffin_1-1756871301489.png

 

This topic has been closed for replies.
Pete_GriffinBest answer
Associate
Sep 3, 2025 9:10 AM UTC

I tried marking all USBD_ClassTypeDef methods as serial output, like this:

Pete_Griffin_0-1756890297644.png

Through the serial port output, I found that when the host sends the URB_ISOCHRONOUS IN request, although the MCU does not enter the USBD_AUDIO_DataIn function, it will enter the USBD_AUDIO_IsoINIncomplete function. After I added the function of sending data to the FIFO, the USB host can receive the data smoothly:

static void FillAudioFrame(void)
{
 float freq = 1000.0f;
 float amp = 10000.0f;

 for (int i = 0; i < 48; i++) {
 int16_t sample = (int16_t)(amp * sinf(2.0f * 3.1415926f * freq * sample_index / 48000.0f));
 usb_buf[i*2] = sample & 0xFF;
 usb_buf[i*2+1] = (sample >> 8) & 0xFF;

 sample_index++;
 if (sample_index >= 48000) sample_index = 0;
 }
}
/**
 * @brief USBD_AUDIO_IsoINIncomplete
 * handle data ISO IN Incomplete event
 * @PAram pdev: device instance
 * @PAram epnum: endpoint index
 * @retval status
 */
static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
	uart2_print("ISO_IN_In\r\n");
	FillAudioFrame(); 
 USBD_LL_Transmit(pdev, AUDIO_IN_EP, usb_buf, AUDIO_IN_PACKET);
 return USBD_OK;
}

WireShark:

Pete_Griffin_1-1756890562319.png

I hope to give some inspiration to other confused people. Thank you to everyone who is watching this post.

4 replies

Associate
Sep 3, 2025 4:47 AM UTC

To add some information, I found that the endpoint type of 0x81 might not be correct, so I changed its type value to 0x01. The following is the display of USB DEVICE TREE:


 =========================== USB Port4 ===========================

Connection Status : 0x01 (Device is connected)
Port Chain : 1-2-4
Properties : 0x01
 IsUserConnectable : yes
 PortIsDebugCapable : no
 PortHasMultiCompanions : no
 PortConnectorIsTypeC : no
ConnectionIndex : 0x04 (Port 4)
CompanionIndex : 0
 CompanionHubSymLnk : USB#VID_05E3&PID_0626#5&369e76a1&0&14#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
 CompanionPortNumber : 0x04 (Port 4)
 -> CompanionPortChain : 1-14-4

 ========================== Summary =========================
Vendor ID : 0x0483 (STMicroelectronics)
Product ID : 0x5740
Manufacturer String : "STMicroelectronics"
Product String : "STM32 Audio Class"
Serial : *ERROR* iSerial=3 but String Descriptor not found
USB Version : 2.0 (but 12 Mbit/s FullSpeed only)
Port maximum Speed : High-Speed (Companion Port 1-14-4 is doing the SuperSpeed)
Device maximum Speed : Full-Speed
Device Connection Speed : Full-Speed
Self powered : no
Demanded Current : 100 mA
Used Endpoints : 1

 ======================== USB Device ========================

 +++++++++++++++++ Device Information ++++++++++++++++++
Device Description : USB Composite Device
Device Path : \\?\USB#VID_0483&PID_5740#6&30502a71&0&4#{a5dcbf10-6530-11d2-901f-00c04fb951ed} (GUID_DEVINTERFACE_USB_DEVICE)
Kernel Name : \Device\USBPDO-14
Device ID : USB\VID_0483&PID_5740\6&30502A71&0&4
Hardware IDs : USB\VID_0483&PID_5740&REV_0200 USB\VID_0483&PID_5740
Driver KeyName : {36fc9e60-c465-11cf-8056-444553540000}\0032 (GUID_DEVCLASS_USB)
Driver : \SystemRoot\System32\drivers\usbccgp.sys (Version: 10.0.19041.2546 Date: 2023-08-23 Company: Microsoft Corporation)
Driver Inf : C:\Windows\inf\usb.inf
Legacy BusType : PNPBus
Class : USB
Class GUID : {36fc9e60-c465-11cf-8056-444553540000} (GUID_DEVCLASS_USB)
Service : usbccgp
Enumerator : USB
Location Info : Port_#0004.Hub_#0005
Address : 4
Location IDs : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(2)#USB(4), ACPI(_SB_)#ACPI(PC00)#ACPI(XHCI)#ACPI(RHUB)#ACPI(HS02)#USB(4)
Container ID : {9a38ccab-8809-11f0-af59-8cb87eaf4566}
Manufacturer Info : (标准 USB 主控制器)
Capabilities : 0x84 (Removable, SurpriseRemovalOK)
Status : 0x0180600A (DN_DRIVER_LOADED, DN_STARTED, DN_DISABLEABLE, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
First Install Date : 2025-09-02 22:42:03
Last Arrival Date : 2025-09-03 12:42:26
Bus Relations : USB\VID_0483&PID_5740&MI_00\7&3a4d92d0&0&0000
EnhancedPowerMgmtEnabled : 0
Power State : D0 (supported: D0, D2, D3, wake from D0, wake from D2)

 +++++++++++++++++ Registry USB Flags +++++++++++++++++
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags\048357400200
 osvc : REG_BINARY 00 00
 NewInterfaceUsage : REG_DWORD 00000000 (0)

 ---------------- Connection Information ---------------
Connection Index : 0x04 (Port 4)
Connection Status : 0x01 (DeviceConnected)
Current Config Value : 0x01 (Configuration 1)
Device Address : 0x1C (28)
Is Hub : 0x00 (no)
Device Bus Speed : 0x01 (Full-Speed)
Number of open Pipes : 0x00 (0 pipes to data endpoints)
Data (HexDump) : 04 00 00 00 12 01 00 02 00 00 00 40 83 04 40 57 ...........@..@W
 00 02 01 02 03 01 01 01 00 1C 00 00 00 00 00 01 ................
 00 00 00 ...

 --------------- Connection Information V2 -------------
Connection Index : 0x04 (4)
Length : 0x10 (16 bytes)
SupportedUsbProtocols : 0x03
 Usb110 : 1 (yes, port supports USB 1.1)
 Usb200 : 1 (yes, port supports USB 2.0)
 Usb300 : 0 (no, port not supports USB 3.0) -> but Companion Port 1-14-4 does
 ReservedMBZ : 0x00
Flags : 0x00
 DevIsOpAtSsOrHigher : 0 (Device is not operating at SuperSpeed or higher)
 DevIsSsCapOrHigher : 0 (Device is not SuperSpeed capable or higher)
 DevIsOpAtSsPlusOrHigher : 0 (Device is not operating at SuperSpeedPlus or higher)
 DevIsSsPlusCapOrHigher : 0 (Device is not SuperSpeedPlus capable or higher)
 ReservedMBZ : 0x00
Data (HexDump) : 04 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 ................

 ---------------------- Device Descriptor ----------------------
bLength : 0x12 (18 bytes)
bDescriptorType : 0x01 (Device Descriptor)
bcdUSB : 0x200 (USB Version 2.0) -> but device is Full-Speed only
bDeviceClass : 0x00 (defined by the interface descriptors)
bDeviceSubClass : 0x00
bDeviceProtocol : 0x00
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0x0483 (STMicroelectronics)
idProduct : 0x5740
bcdDevice : 0x0200
iManufacturer : 0x01 (String Descriptor 1)
 Language 0x0409 : "STMicroelectronics"
iProduct : 0x02 (String Descriptor 2)
 Language 0x0409 : "STM32 Audio Class"
iSerialNumber : 0x03 (String Descriptor 3)
 *!*ERROR String descriptor not found
bNumConfigurations : 0x01 (1 Configuration)
Data (HexDump) : 12 01 00 02 00 00 00 40 83 04 40 57 00 02 01 02 .......@..@W....
 03 01 ..

 ------------------ Configuration Descriptor -------------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x02 (Configuration Descriptor)
wTotalLength : 0x006D (109 bytes)
bNumInterfaces : 0x02 (2 Interfaces)
bConfigurationValue : 0x01 (Configuration 1)
iConfiguration : 0x00 (No String Descriptor)
bmAttributes : 0x80
 D7: Reserved, set 1 : 0x01
 D6: Self Powered : 0x00 (no)
 D5: Remote Wakeup : 0x00 (no)
 D4..0: Reserved, set 0 : 0x00
MaxPower : 0x32 (100 mA)
Data (HexDump) : 09 02 6D 00 02 01 00 80 32 09 04 00 00 00 01 01 ..m.....2.......
 00 00 09 24 01 00 01 27 00 01 01 0C 24 02 01 01 ...$...'....$...
 02 00 01 00 00 00 00 09 24 06 02 01 01 03 00 00 ........$.......
 09 24 03 03 01 01 00 01 00 09 04 01 00 00 01 02 .$..............
 00 00 09 04 01 01 01 01 02 00 00 07 24 01 03 01 ............$...
 01 00 0B 24 02 01 01 02 10 01 80 BB 00 09 05 81 ...$............
 01 60 00 01 00 00 07 25 01 00 00 00 00 .`.....%.....

 ---------------- Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x00 (Interface 0)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x01 (Audio Control)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 00 00 00 01 01 00 00 .........

 ------ Audio Control Interface Header Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (Header)
bcdADC : 0x0100
wTotalLength : 0x0027 (39 bytes)
bInCollection : 0x01
baInterfaceNr[1] : 0x01
Data (HexDump) : 09 24 01 00 01 27 00 01 01 .$...'...

 ------- Audio Control Input Terminal Descriptor -------
bLength : 0x0C (12 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Input Terminal)
bTerminalID : 0x01
wTerminalType : 0x0201 (Microphone)
bAssocTerminal : 0x00
bNrChannels : 0x01 (1 channel)
wChannelConfig : 0x0000 (-)
iChannelNames : 0x00 (No String Descriptor)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 0C 24 02 01 01 02 00 01 00 00 00 00 .$..........

 -------- Audio Control Feature Unit Descriptor --------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x06 (Feature Unit)
bUnitID : 0x02 (2)
bSourceID : 0x01 (1)
bControlSize : 0x01 (1 byte per control)
bmaControls[0] : 0x03
 D0: Mute : 1
 D1: Volume : 1
 D2: Bass : 0
 D3: Mid : 0
 D4: Treble : 0
 D5: Graphic Equalizer : 0
 D6: Automatic Gain : 0
 D7: Delay : 0
bmaControls[1] : 0x00
 D0: Mute : 0
 D1: Volume : 0
 D2: Bass : 0
 D3: Mid : 0
 D4: Treble : 0
 D5: Graphic Equalizer : 0
 D6: Automatic Gain : 0
 D7: Delay : 0
iFeature : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 06 02 01 01 03 00 00 .$.......

 ------- Audio Control Output Terminal Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x03 (Output Terminal)
bTerminalID : 0x03
wTerminalType : 0x0101 (USB Streaming)
bAssocTerminal : 0x00 (0)
bSourceID : 0x01 (1)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 03 03 01 01 00 01 00 .$.......

 ---------------- Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x01 (Interface 1)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 01 00 00 01 02 00 00 .........

 ---------------- Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x01 (Interface 1)
bAlternateSetting : 0x01
bNumEndpoints : 0x01 (1 Endpoint)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 01 01 01 01 02 00 00 .........

 -------- Audio Streaming Interface Descriptor ---------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (AS_GENERAL)
bTerminalLink : 0x03 (Terminal ID 3)
bDelay : 0x01 (1 frame)
wFormatTag : 0x0001 (PCM)
Data (HexDump) : 07 24 01 03 01 01 00 .$.....

 ------- Audio Streaming Format Type Descriptor --------
bLength : 0x0B (11 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Format Type)
bFormatType : 0x01 (FORMAT_TYPE_I)
bNrChannels : 0x01 (1 channel)
bSubframeSize : 0x02 (2 bytes per subframe)
bBitResolution : 0x10 (16 bits per sample)
bSamFreqType : 0x01 (supports 1 sample frequence)
tSamFreq[1] : 0x0BB80 (48000 Hz)
Data (HexDump) : 0B 24 02 01 01 02 10 01 80 BB 00 .$.........

 ----------------- Endpoint Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
bmAttributes : 0x01 (TransferType=Isochronous SyncType=None EndpointType=Data)
wMaxPacketSize : 0x0060 (96 bytes)
bInterval : 0x01 (1 ms)
bRefresh : 0x00
bSynchAddress : 0x00
Data (HexDump) : 09 05 81 01 60 00 01 00 00 ....`....

 ----------- Audio Data Endpoint Descriptor ------------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x25 (Audio Endpoint Descriptor)
bDescriptorSubtype : 0x01 (General)
bmAttributes : 0x00
 D0 : Sampling Freq : 0x00 (not supported)
 D1 : Pitch : 0x00 (not supported)
 D6..2: Reserved : 0x00
 D7 : MaxPacketsOnly : 0x00 (no)
bLockDelayUnits : 0x00 (Undefined)
wLockDelay : 0x0000
Data (HexDump) : 07 25 01 00 00 00 00 .%.....

 ----------------- Device Qualifier Descriptor -----------------
Error : ERROR_GEN_FAILURE (because the device is Full-Speed only)

 -------------------- String Descriptors -------------------
 ------ String Descriptor 0 ------
bLength : 0x04 (4 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language ID[0] : 0x0409 (English - United States)
Data (HexDump) : 04 03 09 04 ....
 ------ String Descriptor 1 ------
bLength : 0x26 (38 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "STMicroelectronics"
Data (HexDump) : 26 03 53 00 54 00 4D 00 69 00 63 00 72 00 6F 00 &.S.T.M.i.c.r.o.
 65 00 6C 00 65 00 63 00 74 00 72 00 6F 00 6E 00 e.l.e.c.t.r.o.n.
 69 00 63 00 73 00 i.c.s.
 ------ String Descriptor 2 ------
bLength : 0x24 (36 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "STM32 Audio Class"
Data (HexDump) : 24 03 53 00 54 00 4D 00 33 00 32 00 20 00 41 00 $.S.T.M.3.2. .A.
 75 00 64 00 69 00 6F 00 20 00 43 00 6C 00 61 00 u.d.i.o. .C.l.a.
 73 00 73 00 s.s.
Andrew Neil
Super User
Sep 3, 2025 8:11 AM UTC

@Pete_Griffin wrote:

trying to use the STM32F411CEU6 as a USB mic.


Your title says USB speaker.

A speaker would not be expected to work as an input device - would it?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate
Sep 3, 2025 9:03 AM UTC

Sorry,I was confused by the error...... but thank you for your prompt response, I have solved the problem through my tireless efforts! :)

Pete_GriffinAuthorBest answer
Associate
Sep 3, 2025 9:10 AM UTC

I tried marking all USBD_ClassTypeDef methods as serial output, like this:

Pete_Griffin_0-1756890297644.png

Through the serial port output, I found that when the host sends the URB_ISOCHRONOUS IN request, although the MCU does not enter the USBD_AUDIO_DataIn function, it will enter the USBD_AUDIO_IsoINIncomplete function. After I added the function of sending data to the FIFO, the USB host can receive the data smoothly:

static void FillAudioFrame(void)
{
 float freq = 1000.0f;
 float amp = 10000.0f;

 for (int i = 0; i < 48; i++) {
 int16_t sample = (int16_t)(amp * sinf(2.0f * 3.1415926f * freq * sample_index / 48000.0f));
 usb_buf[i*2] = sample & 0xFF;
 usb_buf[i*2+1] = (sample >> 8) & 0xFF;

 sample_index++;
 if (sample_index >= 48000) sample_index = 0;
 }
}
/**
 * @brief USBD_AUDIO_IsoINIncomplete
 * handle data ISO IN Incomplete event
 * @PAram pdev: device instance
 * @PAram epnum: endpoint index
 * @retval status
 */
static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
	uart2_print("ISO_IN_In\r\n");
	FillAudioFrame(); 
 USBD_LL_Transmit(pdev, AUDIO_IN_EP, usb_buf, AUDIO_IN_PACKET);
 return USBD_OK;
}

WireShark:

Pete_Griffin_1-1756890562319.png

I hope to give some inspiration to other confused people. Thank you to everyone who is watching this post.