diff options
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | README.md | 101 | ||||
| -rw-r--r-- | avr/boards.txt | 34 | ||||
| -rw-r--r-- | avr/platform.txt | 6 | ||||
| -rwxr-xr-x | verify.sh | 13 |
5 files changed, 127 insertions, 29 deletions
diff --git a/.travis.yml b/.travis.yml index 0f89773..8c97f6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java jdk: - oraclejdk7 env: - - ARDUINO_PACKAGE=arduino-1.5.2-linux64 + - ARDUINO_PACKAGE=arduino-1.5.4-linux64 - ARDUINO_PACKAGE=arduino-nightly-linux64 matrix: allow_failures: @@ -5,14 +5,17 @@ This is a fork of the core Arduino core hardware libraries. The goal is to have a simple base to customize the core libraries to add or modify core functionality, without needing to clone the entire Arduino repository. -Version 1.5.x of the Arduino IDE is required to build projects with this library. +Currently the only addition is support for MIDI-USB for the Arduino Leonardo and similar boards, but this should +serve as a good base for other modifications to the cores libraries. Let me know if you do anything interesting with this! ## Installation and Usage +Version 1.5.4 (or greater) of the Arduino IDE is required to build projects with this library. + 1. Clone this repository. 2. On Linux, run `./install.sh`. The script creates a symlink in ~/Arduino/hardware to the repository. On Windows or Mac you have to do this manually (you may move the repository there instead of creating a symlink). -3. Launch the Arduino IDE (only tested on 1.5.2, will not work pre-1.5.x). +3. Launch the Arduino IDE (only tested on 1.5.4, will not work pre-1.5.x). 4. Under Tools -> Board, select Arduino Leonardo (arcore). 5. Upload your sketch as usual. @@ -23,34 +26,88 @@ This fork currently contains a basic version of USB-MIDI support. It it still un The implementation currently has a single IN and a single OUT endpoint. It can be used together with CDC and HID (as a composite USB device), or standalone (by modifying USBDesc.h). -A simple example that echoes MIDI messages back to the PC: - - void loop() { - while(MIDIUSB.available() > 0) { - MIDIEvent e; - e = MIDIUSB.read(); - MIDIUSB.write(e); - MIDIUSB.flush(); - // Example messages: - // Note on, channel 0, middle C (48), normal velocity (64): - // e = {0x09, 0x90, 48, 64} - // Note off, channel 2, middle C, fastest velocity (127): - // e = {0x08, 0x82, 48, 127} - } - } - -Currently there are no high-level API's. However, the MIDI event format is very simple to read and write. +Currently there are no high-level API's. However, the MIDI event format is very simple to read and write (see examples below). For more info on the MIDI-USB event format, see the official [USB-MIDI specification][2]. -## Other boards +### Send a note-on and note-off every two seconds + +```cpp +// First parameter is the event type (0x09 = note on, 0x08 = note off). +// Second parameter is note-on/note-off, combined with the channel. +// Channel can be anything between 0-15. Typically reported to the user as 1-16. +// Third parameter is the note number (48 = middle C). +// Fourth parameter is the velocity (64 = normal, 127 = fastest). + +void noteOn(byte channel, byte pitch, byte velocity) { + MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity}; + MIDIUSB.write(noteOn); +} + +void noteOff(byte channel, byte pitch, byte velocity) { + MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity}; + MIDIUSB.write(noteOff); +} + +void loop() { + noteOn(0, 48, 64); // Channel 0, middle C, normal velocity + MIDIUSB.flush(); + delay(500); + + noteOff(0, 48, 64); // Channel 0, middle C, normal velocity + MIDIUSB.flush(); + delay(1500); +} + +void setup() { + +} +``` + +### Read and echo MIDI messages back to the PC + +```cpp +void loop() { + while(MIDIUSB.available() > 0) { // Repeat while notes are available to read. + MIDIEvent e; + e = MIDIUSB.read(); + if(e.type == 0x09 || e.type == 0x08) { // Only echo note-on and note-off + MIDIEvent response; + response.type = e.type; // Same event type (note-on/note-off) + response.m1 = e.m1; // Same event type and channel + response.m2 = (e.m2 + 12) % 128; // Shift by one octave + response.m3 = e.m3; // Same velocity + } + MIDIUSB.write(e); + MIDIUSB.flush(); + } +} + +void setup() { + +} +``` + + +## Supported Boards + +This is only officially tested on the Arduino Leonardo. Users have also reported it working on the Arduino Micro and Freeduino Leonardo. Supporting more boards should be as simple as copying the configuration over from the official boards.txt to the one in this repository, - with minor changes to build.core and build.variant. However, I only have an Arduino Leonardo myself, so I cannot test and support any - other boards myself. + with minor changes to build.core and build.variant. ARM (sam) boards might require more work. +## Host support + +This should work out-of-the-box on recent versions of Linux and Mac OS. + +On Windows 7 or later, it might be required to install the Arduino drivers, especially when using it in compound USB mode. + +Windows XP does not support compound devices, but should still work as a plain MIDI device (might also need drivers). Compound mode can be disabled by editing USBDesc.h. + +Users have reported success with iPads. The main requirement here is that the device should not request a high current (as it does by default). A different board configuration, `Arduino Leonardo (arcore, iPad compatible)` is provided for this. + [1]: https://github.com/arduino/Arduino/tree/ide-1.5.x/hardware/arduino/avr/cores [2]: http://www.usb.org/developers/devclass_docs/midi10.pdf diff --git a/avr/boards.txt b/avr/boards.txt index 56ec00a..53720ea 100644 --- a/avr/boards.txt +++ b/avr/boards.txt @@ -28,7 +28,7 @@ leonardo.build.pid=0x8036 leonardo.build.board=AVR_LEONARDO leonardo.build.core=arcore leonardo.build.variant=arduino:leonardo -leonardo.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} +leonardo.build.extra_flags={build.usb_flags} ############################################################## @@ -56,7 +56,37 @@ leonardo2.build.pid=0x8036 leonardo2.build.board=AVR_LEONARDO leonardo2.build.core=arcore leonardo2.build.variant=arduino:leonardo -leonardo2.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DIPAD_COMPAT +leonardo2.build.extra_flags={build.usb_flags} -DIPAD_COMPAT + +############################################################## + +micro.name=Arduino Micro (arcore) +micro.upload.tool=avrdude +micro.upload.protocol=avr109 +micro.upload.maximum_size=28672 +micro.upload.maximum_data_size=2560 +micro.upload.speed=57600 +micro.upload.disable_flushing=true +micro.upload.use_1200bps_touch=true +micro.upload.wait_for_upload_port=true + +micro.bootloader.tool=avrdude +micro.bootloader.low_fuses=0xff +micro.bootloader.high_fuses=0xd8 +micro.bootloader.extended_fuses=0xcb +micro.bootloader.file=caterina/Caterina-Micro.hex +micro.bootloader.unlock_bits=0x3F +micro.bootloader.lock_bits=0x2F + +micro.build.mcu=atmega32u4 +micro.build.f_cpu=16000000L +micro.build.vid=0x2341 +micro.build.pid=0x8037 +micro.build.usb_product="Arduino Micro" +micro.build.board=AVR_MICRO +micro.build.core=arcore +micro.build.variant=arduino:micro +micro.build.extra_flags={build.usb_flags} ############################################################## diff --git a/avr/platform.txt b/avr/platform.txt index c4159f7..c1e17ea 100644 --- a/avr/platform.txt +++ b/avr/platform.txt @@ -74,3 +74,9 @@ tools.avrdude.bootloader.params.verbose=-v -v -v -v tools.avrdude.bootloader.params.quiet=-q -q tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.ide.path}/hardware/arduino/avr/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m + +# USB Default Flags +# Default blank usb manufacturer will be filled it at compile time +# - from numeric vendor ID, set to Unknown otherwise +build.usb_manufacturer= +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' @@ -9,9 +9,11 @@ fi function example { if [[ -f "$ARDUINO_PATH/arduino" ]]; then - echo "Using $ARDUINO_PATH/arduino" cd $ARDUINO_PATH - xvfb-run ./arduino --board arcore:avr:leonardo --verify "$EXAMPLES/$1/$1.ino" + echo + echo "### Verifying example $1 on board $2" + echo "Using $ARDUINO_PATH/arduino" + xvfb-run ./arduino --board "$2" --verify "$EXAMPLES/$1/$1.ino" sleep 1 else echo "Set ARDUINO_PATH to the folder containing the arduino binary" @@ -19,6 +21,9 @@ function example { fi } -example "Empty" -example "MidiEcho" +for board in "arcore:avr:leonardo" "arcore:avr:leonardo2" "arcore:avr:micro" +do + example "Empty" $board + example "MidiEcho" $board +done |
