Skip to content

migrate midi_device to use edpt stream API#3337

Merged
hathach merged 1 commit intomasterfrom
midi-edpt-stream
Nov 12, 2025
Merged

migrate midi_device to use edpt stream API#3337
hathach merged 1 commit intomasterfrom
midi-edpt-stream

Conversation

@hathach
Copy link
Owner

@hathach hathach commented Nov 12, 2025

  • migrate midi_device to use edpt stream API
  • also add tud_midi_n_packet_write/read_n()

Copilot AI review requested due to automatic review settings November 12, 2025 05:29
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the MIDI device class driver from using direct FIFO management to using the new endpoint stream API. This simplifies the code by leveraging the shared stream infrastructure and adds new functions for reading/writing multiple MIDI packets at once.

  • Replaced manual FIFO and endpoint management with tu_edpt_stream_t API
  • Added tud_midi_n_packet_read_n() and tud_midi_n_packet_write_n() functions for bulk packet operations
  • Updated style conventions throughout (const placement, spacing, formatting)

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tusb.c Minor style updates to endpoint stream functions (const placement)
src/common/tusb_private.h Added tu_edpt_stream_is_opened() helper, updated function signatures with const qualifiers, improved comment
src/common/tusb_fifo.h Reorganized declarations, added const qualifiers, moved tu_fifo_empty() to inline implementation
src/common/tusb_fifo.c Removed tu_fifo_empty() function (now inline), added const qualifiers to read-only functions
src/class/vendor/vendor_device.c Added blank line between RX and TX stream operations
src/class/midi/midi_device.h Added new packet batch read/write APIs, updated formatting, removed deprecated functions and comments
src/class/midi/midi_device.c Complete refactor to use tu_edpt_stream_t instead of manual FIFO/endpoint management, implemented new batch packet functions
.clang-format Added IndentPPDirectives: BeforeHash formatting rule

@chatgpt-codex-connector
Copy link

💡 Codex Review

uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets) {
midid_interface_t *p_midi = &_midid_itf[itf];
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str);
n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2);
const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes);
(void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
return n_write;

P1 Badge Return packet count from tud_midi_n_packet_write_n

The new bulk send API advertises that it returns the number of packets written, mirroring tud_midi_n_packet_read_n. However the implementation returns the raw byte count from tu_edpt_stream_write. Callers that divide their buffer based on the returned value will assume four times more packets were queued than actually sent, which can drop data or mis-handle retries. Convert the return value to a packet count (bytes ÷ 4) to keep the API consistent with the read side and the header comment.


TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_write(const uint8_t packet[4]) {
return tud_midi_n_packet_write(0, packet);
}
TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_write_n(const uint8_t packets[], uint32_t n_packets) {
return tud_midi_n_packet_write_n(0, packets, n_packets);

P1 Badge Preserve packet count in tud_midi_packet_write_n wrapper

The single‑interface convenience wrapper for tud_midi_n_packet_write_n returns bool, so any packet count returned by the underlying function is truncated to just success/failure. This makes the new API unusable for callers that need to know how many packets were actually queued. Change the wrapper’s return type to uint32_t (matching the declaration above) so it forwards the packet count instead of discarding it.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@codescene-delta-analysis codescene-delta-analysis bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Health Improved (1 files improve in Code Health)

Gates Failed
Enforce critical code health rules (1 file with Bumpy Road Ahead)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Enforce critical code health rules Violations Code Health Impact
midi_device.c 1 critical rule 7.10 → 7.28 Suppress
View Improvements
File Code Health Impact Categories Improved
midi_device.c 7.10 → 7.28 Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity, Deep, Nested Complexity

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

@hathach hathach force-pushed the midi-edpt-stream branch 2 times, most recently from 51089b5 to e7f8ec5 Compare November 12, 2025 10:32
also add tud_midi_n_packet_write/read_n()
@sonarqubecloud
Copy link

@hathach hathach merged commit 8b8f1f8 into master Nov 12, 2025
219 of 221 checks passed
@hathach hathach deleted the midi-edpt-stream branch November 12, 2025 13:34
Copy link
Collaborator

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI this change increased the CircuitPython arduino_zero build by 532 bytes. I can't easily update to 0.20.0 due to this because some languages now overflow (ru in this case).

It now includes tu_edpt_stream_write_xfer and tu_edpt_stream_read_xfer which are 280 bytes. midid_ init, open, reset and xfer_cb all grow in size as well.

@hathach
Copy link
Owner Author

hathach commented Dec 5, 2025

@tannewt do you have a branch that have wip 0.20.0 (else I will just bump tinyusb submodule in cpy to test with). I will try to see if could reduce the size by dropping features that some smaller ports does not need. This refactor all common edpt stream code so it should reduce code size if e.g cdc and midi both enabled, but I haven't check.

PS: I am trying to optimize the code size for tinyusb, new PR now will have a comment on code size change.

@HiFiPhile
Copy link
Collaborator

I've compared HEAD and 2f0a35f with IAR debug build midi_test:

Header HEAD 2f0a35f
midi_device.o 1578 1490
tusb.o 1964 448
Total 23298 21706

We can reduce size by remove some inline comparing tud_midi_n_available()

Master:
image

2f0a35f:
image

@HiFiPhile
Copy link
Collaborator

I did some test in https://github.com/hathach/tinyusb/tree/size_tweak by:

  • un-inline common used functions
  • unpack 2 packed bitfield, cortex-m is inefficient doing bit-ops

While it's still larger but half-way done ;)

Debug:

Header HEAD 2f0a35f Test
midi_device.o 1578 1490 1430
tusb.o 1964 448 1404
Total 23298 21706 22278

Release:

Header HEAD 2f0a35f Test
midi_device.o 1074 1154 978
tusb.o 1228 300 1002
Total 15840 14994 15466

@hathach
Copy link
Owner Author

hathach commented Dec 5, 2025

is due to extra log in edpt stream that cover all cases such as non-buffered (non-fifo) and xfer_fifo. I will try also to optimize further

@tannewt
Copy link
Collaborator

tannewt commented Dec 5, 2025

@tannewt do you have a branch that have wip 0.20.0 (else I will just bump tinyusb submodule in cpy to test with).

I was testing with adafruit/circuitpython#10736 but didn't end up needing to update TinyUSB. I had done it to the 0.20.0 tag. The tip of master yesterday had even less remaining space.

I was doing the arduino_zero TRANSLATION=ru build in testing. It has CDC and MIDI so it should share the stream code. It is LTOd too. That may make a difference.

@hathach
Copy link
Owner Author

hathach commented Dec 12, 2025

@tannewt #3402 fine tune to reduce the tinyusb foot print. I also add the code metrics which basically sum average all boards/examples for each .c file. The metrics make it easier to follow the code size and make fine tuning later on.

 make BOARD=arduino_zero V=1 TRANSLATION=ru all
QSTR not updated
Module registrations not updated
Root pointer registrations not updated
Memory region         Used Size  Region Size  %age Used
FLASH_BOOTLOADER:           0 B         8 KB      0.00%
  FLASH_FIRMWARE:      188096 B     188160 B     99.97%
FLASH_FILESYSTEM:           0 B        64 KB      0.00%
    FLASH_CONFIG:           0 B          0 B
       FLASH_NVM:           0 B        256 B      0.00%
             RAM:        6456 B        32 KB     19.70%

188096 bytes used, 64 bytes free in flash firmware space out of 188160 bytes (183.75kB).
6444 bytes used, 26324 bytes free in ram for stack and heap out of 32768 bytes (32.0kB).

Converted to uf2, output size: 376320, start address: 0x2000
Wrote 376320 bytes to build-arduino_zero/firmware.uf2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants