Skip to main content
Associate
September 3, 2025
Solved

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

  • September 3, 2025
  • 3 replies
  • 713 views

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

 

Best answer by Pete_Griffin

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.

3 replies

Associate
September 3, 2025

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
September 3, 2025

@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
September 3, 2025

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
September 3, 2025

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.