Created
June 18, 2025 11:11
-
-
Save TomWhitwell/a7023fb08c8570e4fb55077bc7cf05da to your computer and use it in GitHub Desktop.
Notes on fix for Music Thing Workshop System MIDI on Windows devices
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Solutions in these notes entirely generated by ChatGPT - use with caution | |
1 Service the USB device every pass through loop() | |
Symptom fixed: hard-fault a few seconds after Windows starts flooding the control endpoint. | |
Windows sends class–specific SET_INTERFACE / SET_CUR requests in quick bursts; if the device | |
code is busy in analogRead() etc. and never re-enters TinyUSB for > ~3 ms the control EP0 | |
state machine underflows and panics. | |
void loop() { | |
// --- PATCH 1: keep TinyUSB alive on Windows ------------- | |
TinyUSBDevice.task(); // << NEW – poll USB engine | |
2 Trim over-long string descriptors (< 31 chars) | |
Windows’ built-in USB-Audio/MIDI driver rejects interface strings ≥ 32 UTF-16 code-units and tears | |
the whole device down . | |
Your current strings are 32 chars long. | |
void setup() { | |
// Initialise MIDI | |
- TinyUSBDevice.setManufacturerDescriptor("Music Thing Modular"); | |
- TinyUSBDevice.setProductDescriptor("Workshop System MIDI"); | |
+ TinyUSBDevice.setManufacturerDescriptor("MT Modular"); | |
+ TinyUSBDevice.setProductDescriptor("Workshop MIDI"); | |
3 Give Windows a unique iSerialNumber | |
Without one, each time you plug into a new USB port Windows adds a fresh registry entry, | |
quickly exhausting the 10-device MIDI quota and corrupting earlier entries | |
– after which new connections crash during enumeration. | |
Add just after the other descriptors: | |
#include "pico/unique_id.h" // <-- NEW | |
void setup() { | |
... | |
+ // --- PATCH 3: per-board serial number ------------------- | |
+ char serial[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1]; | |
+ pico_get_unique_board_id_string(serial, sizeof serial); | |
+ TinyUSBDevice.setSerialDescriptor(serial); | |
NB: I'm not certain this is working | |
4 Enlarge TinyUSB’s MIDI FIFOs (Windows bursts > 64 bytes) | |
Windows DAWs often dump several hundred bytes of parameter state immediately after opening a port. | |
With the default 64-byte RX buffer TinyUSB overruns, asserts, and the RP2040 reboots | |
#define CFG_TUD_MIDI_RX_BUFSIZE 512 | |
#define CFG_TUD_MIDI_TX_BUFSIZE 512 | |
#define CFG_TUD_MIDI_EP_BUFSIZE 64 | |
5 Throttle your own CC spam just enough | |
Even with bigger FIFOs you’re sending up to 8 CCs every ~2 ms when a DAW is also sending data. | |
Give TinyUSB a chance to flush: | |
if (analog[i]->hasChanged()) { | |
MIDI.sendControlChange(45 + i, analog[i]->getValue() >> 5, 1); | |
- delay(1); // old | |
+ tud_task(); // << replace delay with USB poll | |
} | |
delay(1) blocks interrupts; tud_task() services USB and returns in ~30 µs. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment