diff --git a/extra_script.py b/extra_script.py new file mode 100644 index 0000000..fda0754 --- /dev/null +++ b/extra_script.py @@ -0,0 +1,3 @@ +Import("env") + +env.Append(LINKFLAGS=["-Wl,--allow-multiple-definition"]) diff --git a/platformio.ini b/platformio.ini index 0305f7d..01ceb8a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,8 +6,17 @@ platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino lib_deps = + adafruit/Adafruit TinyUSB Library@3.1.0 fastled/FastLED@^3.9.0 +build_unflags = + -DARDUINO_USB_MODE=1 + +build_flags = + -DARDUINO_USB_MODE=0 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DUSE_TINYUSB=1 + monitor_speed = 115200 board_build.partitions = default_8MB.csv diff --git a/src/main.cpp b/src/main.cpp index 95ae309..408833e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include #include #include "midi_transport.h" +#include "Adafruit_TinyUSB.h" #include "pixel_stomp_mux.h" #include "led_stub.h" #include "switch_stub.h" @@ -83,8 +84,8 @@ void handle_serial_command(const String& cmd) { mux.show(); Serial.println("[CMD] Pixel 1 WHITE (max brightness)"); } else if (cmd == "usb") { - Serial.printf("[CMD] USB mounted: %s\n", USB.mounted() ? "YES" : "NO"); - Serial.printf("[CMD] USB ready: %s\n", USB.ready() ? "YES" : "NO"); + Serial.printf("[CMD] USB mounted: %s\n", TinyUSBDevice.mounted() ? "YES" : "NO"); + Serial.printf("[CMD] USB ready: %s\n", TinyUSBDevice.ready() ? "YES" : "NO"); } else if (cmd == "gpiotest") { Serial.println("[CMD] === Raw GPIO Test ==="); uint8_t pins[] = {9, 10, 11, 12}; diff --git a/src/midi_transport.cpp b/src/midi_transport.cpp index b8b8220..322fe7f 100644 --- a/src/midi_transport.cpp +++ b/src/midi_transport.cpp @@ -1,8 +1,8 @@ #include "midi_transport.h" #include -#include "USB.h" +#include "Adafruit_TinyUSB.h" -static USBMIDI usb_midi; +static Adafruit_USBD_MIDI usb_midi; UsbMidiTransport::UsbMidiTransport() : initialized(false) { } @@ -13,12 +13,24 @@ UsbMidiTransport::~UsbMidiTransport() { bool UsbMidiTransport::begin() { Serial.println("[MIDI] Setting up USB MIDI device..."); + if (!TinyUSBDevice.isInitialized()) { + TinyUSBDevice.setManufacturerDescriptor("Ashley Strahle"); + TinyUSBDevice.setProductDescriptor("Loopy Foot Controller"); + TinyUSBDevice.setSerialDescriptor("LFMIDI001"); + TinyUSBDevice.begin(0); + } + if (!usb_midi.begin()) { Serial.println("[MIDI] ERROR: USB MIDI init failed"); return false; } - USB.begin(); + if (TinyUSBDevice.mounted()) { + Serial.println("[MIDI] Re-enumerating with MIDI interface..."); + TinyUSBDevice.detach(); + delay(10); + TinyUSBDevice.attach(); + } initialized = true; Serial.println("[MIDI] USB MIDI ready - enumerating..."); @@ -32,7 +44,8 @@ void UsbMidiTransport::update() { uint32_t now = millis(); if (now - last_status > 5000) { last_status = now; - Serial.printf("[MIDI] USB ready: %s\n", USB.ready() ? "YES" : "NO"); + Serial.printf("[MIDI] USB mounted: %s\n", + TinyUSBDevice.mounted() ? "YES" : "NO"); } while (usb_midi.available()) { @@ -65,24 +78,27 @@ void UsbMidiTransport::on_midi_receive(std::function cal void UsbMidiTransport::send_note_on(uint8_t channel, uint8_t note, uint8_t velocity) { if (!initialized) return; - usb_midi.noteOn(note, velocity, channel); + uint8_t packet[4] = {0x09, (uint8_t)(0x90 | (channel - 1)), note, velocity}; + usb_midi.writePacket(packet); Serial.printf("[MIDI OUT] Ch:%d NOTE_ON:%d:%d\n", channel, note, velocity); } void UsbMidiTransport::send_note_off(uint8_t channel, uint8_t note, uint8_t velocity) { if (!initialized) return; - usb_midi.noteOff(note, velocity, channel); + uint8_t packet[4] = {0x08, (uint8_t)(0x80 | (channel - 1)), note, velocity}; + usb_midi.writePacket(packet); Serial.printf("[MIDI OUT] Ch:%d NOTE_OFF:%d:%d\n", channel, note, velocity); } void UsbMidiTransport::send_cc(uint8_t channel, uint8_t cc, uint8_t value) { if (!initialized) return; - usb_midi.controlChange(cc, value, channel); + uint8_t packet[4] = {0x0B, (uint8_t)(0xB0 | (channel - 1)), cc, value}; + usb_midi.writePacket(packet); Serial.printf("[MIDI OUT] Ch:%d CC:%d:%d\n", channel, cc, value); } bool UsbMidiTransport::is_connected() { - return initialized && USB.ready(); + return initialized && TinyUSBDevice.mounted(); } void UsbMidiTransport::parse_midi_packet(const uint8_t* buffer, uint32_t size, MidiEvent& event) {