From 9c49c0eb215057885ae0aec46172778b9cf9b9a5 Mon Sep 17 00:00:00 2001 From: Hakan Lindestaf Date: Wed, 22 Apr 2026 17:48:07 -0500 Subject: midi host: raise default RX FIFO above EP size, document drain requirement Follow-up to #3239. tuh_midi_stream_read terminates on cable-number transitions, leaving residue in the FIFO. With the default RX FIFO sized equal to one bulk packet, the next bulk IN transfer fails to queue and the driver silently stops receiving. Raising the default to 2x bulk gives single-call apps a full packet of headroom and documents the drain-loop expectation. Reproduced with Akai LPD8 mk1 (VID 09E8 PID 0075) on STM32H753 DWC2 host; fixed with this patch. See #3613 for full repro + captures. --- src/class/midi/midi_host.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index b9ab0130d..4eefed4ba 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,11 +38,16 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX + // Default sized to 2x the bulk endpoint to absorb residue left in the FIFO + // when tuh_midi_stream_read() stops early on a cable-number transition. + // Sizing this equal to the endpoint packet size (the historical default) + // can cause the next bulk IN transfer to fail to queue silently, wedging + // the stream. See the drain-loop note on tuh_midi_stream_read() below. + #define CFG_TUH_MIDI_RX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX + #define CFG_TUH_MIDI_TX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE @@ -150,6 +155,13 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, const uint8_t *p_ // Note that this function ignores the CIN field of the MIDI packet // because a number of commercial devices out there do not encode // it properly. +// +// NOTE: this function terminates when it encounters an event whose cable +// number differs from the one being returned. Applications should invoke +// it in a loop until it returns 0 (or until tuh_midi_read_available() +// returns 0) to guarantee the stream FIFO is fully drained per callback. +// Leaving bytes in the FIFO across callbacks can prevent subsequent bulk +// IN transfers from landing. uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize); #endif -- cgit v1.3.1 From d24cf89e4896ee959c034818bd4ecb6210714042 Mon Sep 17 00:00:00 2001 From: Hakan Lindestaf Date: Wed, 22 Apr 2026 23:32:05 +0000 Subject: Revert MIDI TX buffer size definition --- src/class/midi/midi_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 4eefed4ba..000d815c4 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -47,7 +47,7 @@ extern "C" { #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE -- cgit v1.3.1 From e557f94c721871246ee7ac0761d74e5f8794300f Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Thu, 7 May 2026 11:17:57 +0200 Subject: revert RX buffer size as it's not related to issue Even if CFG_TUH_MIDI_RX_BUFSIZE=100*TUH_EPSIZE_BULK_MAX, calling tuh_midi_stream_read without a loop can return only one 4-byte packet and preventing subsequent transfer. Signed-off-by: Zixun LI --- src/class/midi/midi_host.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 000d815c4..8fdfd8966 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,12 +38,7 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - // Default sized to 2x the bulk endpoint to absorb residue left in the FIFO - // when tuh_midi_stream_read() stops early on a cable-number transition. - // Sizing this equal to the endpoint packet size (the historical default) - // can cause the next bulk IN transfer to fail to queue silently, wedging - // the stream. See the drain-loop note on tuh_midi_stream_read() below. - #define CFG_TUH_MIDI_RX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE -- cgit v1.3.1