Skip to main content
JianNan
Associate
July 4, 2026
Solved

An exception occurred when transplanting Ux_Device_Audio_2.0_Standalone of STM32WBA6

  • July 4, 2026
  • 4 replies
  • 86 views

Thank you for taking the time to review my question.

I migrated the Ux_Device_Audio_2.0_Standalone of STM32WBA6 to STM32H503 and successfully enumerated using USB FS. However, out of 1000 entries into the USBD_AUDIO_PlaybackStreamFrameDone function per second, half are 4 bytes long and half are 384 bytes (audio stream). I monitored the data using USBlyzer and did not see any upload data (EP IN) from STM32H503. I don't know where these 4 bytes come from, and this issue has been bothering me for several days.

VOID USBD_AUDIO_PlaybackStreamFrameDone(UX_DEVICE_CLASS_AUDIO_STREAM *audio_play_stream,
ULONG length)
{
/* USER CODE BEGIN USBD_AUDIO_PlaybackStreamFrameDone */

UCHAR *frame_buffer;
ULONG frame_length;
int32_t ret;

UNUSED(ret);

/* Get access to first audio input frame. */
ux_device_class_audio_read_frame_get(audio_play_stream, &frame_buffer, &frame_length);


if (length)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
printf("%d\n", length);
if (BufferCtl.wr_ptr > USB_AUDIO_BUF_SIZE - frame_length)
{
/* Not enough space in buffer: copy remaining space available and rollback */
uint32_t partial_copy_len = USB_AUDIO_BUF_SIZE - BufferCtl.wr_ptr;

ux_utility_memory_copy(&BufferCtl.buff[BufferCtl.wr_ptr], frame_buffer, partial_copy_len);
ux_utility_memory_copy(&BufferCtl.buff[0], frame_buffer + partial_copy_len, frame_length - partial_copy_len);
BufferCtl.wr_ptr = frame_length - partial_copy_len;
}
else
{
/* Enough space in buffer: copy data */
ux_utility_memory_copy(&BufferCtl.buff[BufferCtl.wr_ptr], frame_buffer, frame_length);
BufferCtl.wr_ptr += frame_length;
}

/* Check trigger for Audio DMA start (half of buffer full) */
if ((BufferCtl.rd_enable == 0) && ((BufferCtl.wr_ptr - BufferCtl.rd_ptr) > USB_AUDIO_BUF_SIZE / 2))
{
/* Start Audio DMA */
BufferCtl.rd_enable = 1;

memcpy(&DMABuffer[0], &BufferCtl.buff[0], I2S_AUDIO_BUF_SIZE);
BufferCtl.rd_ptr = I2S_AUDIO_BUF_SIZE;

ret = HAL_I2S_Transmit_DMA(&hi2s1, (uint16_t*)&DMABuffer[0], I2S_AUDIO_BUF_SIZE/4);
if(ret != 0) printf("HAL_I2S_Transmit_DMA fail:%ld\n", ret);
}
}

/* Re-free the first audio input frame for transfer. */
ux_device_class_audio_read_frame_free(audio_play_stream);

ComputeUSBFeedback(audio_play_stream);

/* USER CODE END USBD_AUDIO_PlaybackStreamFrameDone */

return;
}

 

Best answer by JianNan

Replaced the Feedback endpoint with another endpoint to solve the problem, not using the same endpoint as the audio stream output.

4 replies

Visitor II
July 4, 2026

This looks like an explicit Feedback Endpoint data mismatch or descriptor misconfiguration between the MCU architectures. The alternating 4-byte packages usually occur when the host tracks asynchronous clock drift, but the endpoint reads it within the main audio stream handler loop instead of routing it separately.

We optimize similar fast callback structures and dynamic execution pipelines on our platform, Deen Elevated, where eliminating backend latency bottlenecks is critical. Double-check your endpoints and FIFO structure in usbd_conf.c for the H5.

JianNan
JianNanAuthor
Associate
July 4, 2026
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x81, PCD_SNG_BUF, 0x06C0);

I configured 0x81 for Feedback, but I didn't see the host issue  Isochronous transfer input request. The 4 bytes seem to come from USBX.

If 0x81 is not configured for Feedback, the UAC2.0 device cannot be enumerated properly.

JianNan
JianNanAuthorBest answer
Associate
July 5, 2026

Replaced the Feedback endpoint with another endpoint to solve the problem, not using the same endpoint as the audio stream output.