From 8e2d74b8c915c02de242989c70daa5133178ec9a Mon Sep 17 00:00:00 2001 From: Nicola Jaggi Date: Mon, 27 Jul 2026 12:09:08 +0200 Subject: [PATCH] fix: skip zero-length ISO OUT packets in audio read thread A zero-length isochronous OUT transfer (actual_length == 0) carries no audio data, but the read thread still recorded it as a frame: it wrote frame_length = 0 into the slot at transfer_pos, advanced transfer_pos and fired the frame_done callback. Because the frame FIFO uses frame_length == 0 as the sentinel for an empty slot, this made the slot indistinguishable from a free one. The consumer then read at access_pos, saw frame_length == 0, reported it as an underflow (UX_BUFFER_OVERFLOW) and did not advance access_pos. As a result transfer_pos moved forward while access_pos stayed put, permanently desyncing the producer/consumer positions. Skip zero-length packets entirely: leave transfer_pos in place, do not fire the callback, and re-issue the transfer at the same slot. This preserves the "frame_length == 0 means empty slot" invariant and keeps the transfer and access positions in sync. --- .../src/ux_device_class_audio_read_thread_entry.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c index 0badadd9f..be416b5b2 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c @@ -129,6 +129,10 @@ ULONG actual_length; /* Get actual transfer length. */ actual_length = transfer -> ux_slave_transfer_request_actual_length; + + if (actual_length == 0) { + continue; + } /* Frame received, log it. */ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length = actual_length;