aboutsummaryrefslogtreecommitdiffstats
path: root/Bootloaders/Incomplete/MIDI/JavaHost
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-09-30 04:40:36 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-09-30 04:40:36 +0000
commit89c837ee34db186f7b1f859f767d587036573c4c (patch)
tree0fd7efe823b1924c89628052398851e54b92fe06 /Bootloaders/Incomplete/MIDI/JavaHost
parent059ebd01a3f34ce288adfe30c6cd5b88553882fa (diff)
downloadlufa-89c837ee34db186f7b1f859f767d587036573c4c.tar.gz
lufa-89c837ee34db186f7b1f859f767d587036573c4c.tar.bz2
lufa-89c837ee34db186f7b1f859f767d587036573c4c.zip
Removed mostly useless "TestApp" demo, as it was mainly useful only for checking for sytax errors in the library.
MIDI device demos now receive MIDI events from the host and display note ON messages via the board LEDs. Added beginnings of a MIDI class bootloader.
Diffstat (limited to 'Bootloaders/Incomplete/MIDI/JavaHost')
-rw-r--r--Bootloaders/Incomplete/MIDI/JavaHost/BIN2BOOT.java178
-rw-r--r--Bootloaders/Incomplete/MIDI/JavaHost/MIDIMessageReceiver.java33
2 files changed, 211 insertions, 0 deletions
diff --git a/Bootloaders/Incomplete/MIDI/JavaHost/BIN2BOOT.java b/Bootloaders/Incomplete/MIDI/JavaHost/BIN2BOOT.java
new file mode 100644
index 000000000..f30998ad5
--- /dev/null
+++ b/Bootloaders/Incomplete/MIDI/JavaHost/BIN2BOOT.java
@@ -0,0 +1,178 @@
+import javax.sound.midi.*;
+import javax.sound.midi.MidiMessage.*;
+import java.io.RandomAccessFile;
+
+class BIN2BOOT
+{
+ private static final int MIDI_CONTROL_CHANNEL = 9;
+ private static final int MIDI_DATA_CHANNEL = 0;
+
+ private static final int CONTROL_DEVICE_READY = 0xD1;
+ private static final int CONTROL_ENTER_PROG_MODE = 0xDC;
+ private static final int CONTROL_LEAVE_PROG_MODE = 0xDF;
+ private static final int CONTROL_GET_PAGE_SIZE = 0x01;
+
+ public static void main(String[] args)
+ {
+ if (args.length != 1)
+ {
+ System.out.println("BIN2BOOT - USB-MIDI bootloader");
+ System.out.println(" Usage: java BIN2BOOT {input}.bin");
+ }
+
+ RandomAccessFile inFile = null;
+
+ try
+ {
+ inFile = new RandomAccessFile(args[0], "r");
+ }
+ catch (Exception e)
+ {
+ System.out.println("Could not open input file!");
+ return;
+ }
+
+ MidiDevice currDevice = null;
+ Receiver midiOut = null;
+ Transmitter midiIn = null;
+ MIDIMessageReceiver midiInMessages = new MIDIMessageReceiver();
+
+ try
+ {
+ MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+
+ for (MidiDevice.Info info : infos)
+ {
+ currDevice = MidiSystem.getMidiDevice(info);
+
+ if (!(currDevice instanceof Sequencer) && !(currDevice instanceof Synthesizer))
+ {
+ if (info.getName().indexOf("LUFA") == -1)
+ continue;
+
+ System.out.println(" MIDI Device: " + info.getName());
+
+ currDevice.open();
+
+ if (currDevice.getMaxReceivers() != 0)
+ {
+ midiOut = currDevice.getReceiver();
+ break;
+ }
+
+ if (currDevice.getMaxTransmitters() != 0)
+ {
+ midiIn = currDevice.getTransmitter();
+ midiIn.setReceiver(midiInMessages);
+ }
+ }
+ }
+
+ if ((midiOut == null) || (midiIn == null))
+ {
+ System.out.println("Could not find suitable MIDI device!");
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println("Could not enumerate MIDI devices!");
+ return;
+ }
+
+ System.out.println("PROGRAMMING FILE...");
+
+ ProgramFirmware(inFile, midiOut, midiInMessages);
+
+ System.out.println("DONE.");
+
+ try
+ {
+ midiOut.close();
+ midiIn.close();
+ currDevice.close();
+ inFile.close();
+ }
+ catch (Exception e)
+ {
+ System.out.println("ERROR: Could not close open resources.");
+ }
+ }
+
+ private static void ProgramFirmware(RandomAccessFile inFile, Receiver midiOut, MIDIMessageReceiver midiInMessages)
+ {
+ try
+ {
+ System.out.println("Entering Programming Mode...");
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_ENTER_PROG_MODE);
+
+ int[] messageData;
+ do
+ {
+ messageData = receiveByteViaMIDI(midiInMessages);
+ }
+ while ((messageData[0] != MIDI_CONTROL_CHANNEL) && (messageData[1] != CONTROL_DEVICE_READY));
+
+ System.out.println("Getting Page Size...");
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_GET_PAGE_SIZE);
+
+ int nextByte = inFile.read();
+ while (nextByte != -1)
+ {
+ sendByteViaMIDI(midiOut, 9, nextByte);
+
+ if ((inFile.getFilePointer() % (inFile.length() / 100)) == 0)
+ System.out.println(" LOADING: " + (int)(inFile.getFilePointer() / (inFile.length() / 100.0)) + "%...");
+
+ nextByte = inFile.read();
+ }
+
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_LEAVE_PROG_MODE);
+ }
+ catch (Exception e)
+ {
+ System.out.println("ERROR: Could not send data to device.");
+ }
+ }
+
+ private static void sendByteViaMIDI(Receiver midiOut, int channel, int data)
+ {
+ ShortMessage sendMessage = new ShortMessage();
+
+ try
+ {
+ sendMessage.setMessage(ShortMessage.NOTE_ON, channel, (data & 0x7F), (((data & 0x80) == 0x80) ? 64 : 32));
+ midiOut.send(sendMessage, -1);
+
+// try {Thread.sleep(1);} catch (Exception e) {}
+
+ sendMessage.setMessage(ShortMessage.NOTE_OFF, channel, (data & 0x7F), (((data & 0x80) == 0x80) ? 64 : 32));
+ midiOut.send(sendMessage, -1);
+ }
+ catch (Exception e)
+ {
+ System.out.println("ERROR: Could not send MIDI note press.");
+ }
+ }
+
+ private static int[] receiveByteViaMIDI(MIDIMessageReceiver midiInReceiver)
+ {
+ byte[] messageData;
+
+ do
+ {
+ while (!(midiInReceiver.hasReceived()));
+ messageData = midiInReceiver.receive().getMessage();
+ }
+ while ((messageData[0] & 0xF0) != ShortMessage.NOTE_ON);
+
+ int channel = (messageData[0] & 0x0F);
+ int data = (messageData[1] | ((messageData[2] == 64) ? 0x80 : 0x00));
+
+ int[] formattedMessageData = new int[2];
+ formattedMessageData[0] = channel;
+ formattedMessageData[1] = data;
+
+ return formattedMessageData;
+ }
+} \ No newline at end of file
diff --git a/Bootloaders/Incomplete/MIDI/JavaHost/MIDIMessageReceiver.java b/Bootloaders/Incomplete/MIDI/JavaHost/MIDIMessageReceiver.java
new file mode 100644
index 000000000..0fcaaead9
--- /dev/null
+++ b/Bootloaders/Incomplete/MIDI/JavaHost/MIDIMessageReceiver.java
@@ -0,0 +1,33 @@
+import java.util.PriorityQueue;
+import javax.sound.midi.*;
+import javax.sound.midi.MidiMessage.*;
+
+class MIDIMessageReceiver implements Receiver
+{
+ private PriorityQueue<MidiMessage> messages;
+
+ MIDIMessageReceiver()
+ {
+ messages = new PriorityQueue<MidiMessage>();
+ }
+
+ public void send(MidiMessage message, long timeStamp)
+ {
+ messages.add(message);
+ }
+
+ public boolean hasReceived()
+ {
+ return (messages.size() != 0);
+ }
+
+ public MidiMessage receive()
+ {
+ return messages.poll();
+ }
+
+ public void close()
+ {
+
+ }
+}