From 88196051e8bd89b282fda8d395f4c333425a91b1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Mar 2026 19:04:13 +0700 Subject: [PATCH] fix bugs in fsdev hcd, dcd and midi host stream write - hcd_edpt_clear_stall: use ep_addr instead of hardcoded 0 (control endpoint) - hcd: add TUP_USBIP_FSDEV_DRD define for MCUs with host support (C0, G0, H5, U3, U5) and use it in hcd compile guard instead of enumerating MCUs - dcd_edpt_close_all: use FSDEV_EP_COUNT instead of CFG_TUD_ENDPPOINT_MAX for PMA btable offset to match handle_bus_reset - midi host tuh_midi_stream_write: add missing cable_num to system messages, SysEx, and real-time MIDI packets. Add 0xF mask for SysEx CIN checks. Aligns with midi_device.c tud_midi_n_stream_write implementation. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/class/midi/midi_host.c | 11 ++++++----- src/common/tusb_mcu.h | 5 +++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c | 7 ++----- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 8d59dfc66..a53546404 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -461,7 +461,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away midi_driver_stream_t streamrt; - streamrt.buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + streamrt.buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; @@ -476,9 +476,9 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. - if (stream->buffer[0] == MIDI_CIN_SYSEX_START) { + if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START) { if (data == MIDI_STATUS_SYSEX_END) { - stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); stream->total = 2; } else { stream->total = 4; @@ -506,6 +506,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; } + stream->buffer[0] |= (uint8_t)(cable_num << 4); } else { // Pack individual bytes if we don't support packing them into words. stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); @@ -520,8 +521,8 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu stream->buffer[stream->index] = data; stream->index++; // See if this byte ends a SysEx. - if (stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { - stream->buffer[0] = MIDI_CIN_SYSEX_START + (stream->index - 1); + if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { + stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); stream->total = stream->index; } } diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 34dd6af8d..b12a3177e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -202,6 +202,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32C0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32F0) @@ -278,6 +279,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32G0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32G4) @@ -293,6 +295,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32H5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -366,6 +369,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32U3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32U5) @@ -373,6 +377,7 @@ #if defined(STM32U535xx) || defined(STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #else #define TUP_USBIP_DWC2 diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 13d1a6cb4..8b4719b21 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -612,7 +612,7 @@ void dcd_edpt_close_all(uint8_t rhport) { dcd_int_enable(rhport); // Reset PMA allocation - ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c index dd86b052a..18685dbdc 100644 --- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c @@ -38,8 +38,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && \ - TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32G0, OPT_MCU_STM32H5, OPT_MCU_STM32U5) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && defined(TUP_USBIP_FSDEV_DRD) #include "host/hcd.h" #include "host/usbh.h" @@ -672,10 +671,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet // Clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; - (void) dev_addr; - (void) ep_addr; - uint8_t const ep_id = endpoint_find(dev_addr, 0); + uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];