--- /dev/null
+import javax.sound.midi.*;\r
+import javax.sound.midi.MidiMessage.*;\r
+import java.io.RandomAccessFile;\r
+\r
+class BIN2BOOT\r
+{\r
+ private static final int MIDI_CONTROL_CHANNEL = 9;\r
+ private static final int MIDI_DATA_CHANNEL = 0;\r
+\r
+ private static final int CONTROL_DEVICE_READY = 0xD1;\r
+ private static final int CONTROL_ENTER_PROG_MODE = 0xDC;\r
+ private static final int CONTROL_LEAVE_PROG_MODE = 0xDF;\r
+ private static final int CONTROL_GET_PAGE_SIZE = 0x01;\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ if (args.length != 1)\r
+ {\r
+ System.out.println("BIN2BOOT - USB-MIDI bootloader");\r
+ System.out.println(" Usage: java BIN2BOOT {input}.bin");\r
+ } \r
+ \r
+ RandomAccessFile inFile = null;\r
+ \r
+ try\r
+ {\r
+ inFile = new RandomAccessFile(args[0], "r");\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.out.println("Could not open input file!");\r
+ return;\r
+ }\r
+\r
+ MidiDevice currDevice = null;\r
+ Receiver midiOut = null;\r
+ Transmitter midiIn = null;\r
+ MIDIMessageReceiver midiInMessages = new MIDIMessageReceiver();\r
+ \r
+ try\r
+ {\r
+ MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();\r
+ \r
+ for (MidiDevice.Info info : infos)\r
+ {\r
+ currDevice = MidiSystem.getMidiDevice(info);\r
+ \r
+ if (!(currDevice instanceof Sequencer) && !(currDevice instanceof Synthesizer))\r
+ {\r
+ if (info.getName().indexOf("LUFA") == -1)\r
+ continue;\r
+ \r
+ System.out.println(" MIDI Device: " + info.getName());\r
+ \r
+ currDevice.open();\r
+ \r
+ if (currDevice.getMaxReceivers() != 0)\r
+ {\r
+ midiOut = currDevice.getReceiver();\r
+ break;\r
+ }\r
+\r
+ if (currDevice.getMaxTransmitters() != 0)\r
+ {\r
+ midiIn = currDevice.getTransmitter();\r
+ midiIn.setReceiver(midiInMessages);\r
+ }\r
+ }\r
+ }\r
+ \r
+ if ((midiOut == null) || (midiIn == null))\r
+ {\r
+ System.out.println("Could not find suitable MIDI device!");\r
+ return;\r
+ } \r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.out.println("Could not enumerate MIDI devices!");\r
+ return;\r
+ }\r
+ \r
+ System.out.println("PROGRAMMING FILE...");\r
+\r
+ ProgramFirmware(inFile, midiOut, midiInMessages);\r
+\r
+ System.out.println("DONE.");\r
+\r
+ try\r
+ {\r
+ midiOut.close();\r
+ midiIn.close();\r
+ currDevice.close();\r
+ inFile.close();\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.out.println("ERROR: Could not close open resources."); \r
+ }\r
+ }\r
+ \r
+ private static void ProgramFirmware(RandomAccessFile inFile, Receiver midiOut, MIDIMessageReceiver midiInMessages)\r
+ {\r
+ try\r
+ {\r
+ System.out.println("Entering Programming Mode...");\r
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_ENTER_PROG_MODE);\r
+ \r
+ int[] messageData;\r
+ do\r
+ {\r
+ messageData = receiveByteViaMIDI(midiInMessages);\r
+ }\r
+ while ((messageData[0] != MIDI_CONTROL_CHANNEL) && (messageData[1] != CONTROL_DEVICE_READY));\r
+ \r
+ System.out.println("Getting Page Size...");\r
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_GET_PAGE_SIZE);\r
+\r
+ int nextByte = inFile.read();\r
+ while (nextByte != -1)\r
+ {\r
+ sendByteViaMIDI(midiOut, 9, nextByte);\r
+\r
+ if ((inFile.getFilePointer() % (inFile.length() / 100)) == 0)\r
+ System.out.println(" LOADING: " + (int)(inFile.getFilePointer() / (inFile.length() / 100.0)) + "%...");\r
+\r
+ nextByte = inFile.read();\r
+ }\r
+\r
+ sendByteViaMIDI(midiOut, MIDI_CONTROL_CHANNEL, CONTROL_LEAVE_PROG_MODE);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.out.println("ERROR: Could not send data to device."); \r
+ }\r
+ }\r
+\r
+ private static void sendByteViaMIDI(Receiver midiOut, int channel, int data)\r
+ {\r
+ ShortMessage sendMessage = new ShortMessage();\r
+ \r
+ try\r
+ {\r
+ sendMessage.setMessage(ShortMessage.NOTE_ON, channel, (data & 0x7F), (((data & 0x80) == 0x80) ? 64 : 32));\r
+ midiOut.send(sendMessage, -1);\r
+\r
+// try {Thread.sleep(1);} catch (Exception e) {}\r
+\r
+ sendMessage.setMessage(ShortMessage.NOTE_OFF, channel, (data & 0x7F), (((data & 0x80) == 0x80) ? 64 : 32));\r
+ midiOut.send(sendMessage, -1);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.out.println("ERROR: Could not send MIDI note press.");\r
+ }\r
+ }\r
+\r
+ private static int[] receiveByteViaMIDI(MIDIMessageReceiver midiInReceiver)\r
+ {\r
+ byte[] messageData;\r
+ \r
+ do\r
+ {\r
+ while (!(midiInReceiver.hasReceived()));\r
+ messageData = midiInReceiver.receive().getMessage();\r
+ }\r
+ while ((messageData[0] & 0xF0) != ShortMessage.NOTE_ON);\r
+ \r
+ int channel = (messageData[0] & 0x0F);\r
+ int data = (messageData[1] | ((messageData[2] == 64) ? 0x80 : 0x00));\r
+ \r
+ int[] formattedMessageData = new int[2];\r
+ formattedMessageData[0] = channel;\r
+ formattedMessageData[1] = data;\r
+ \r
+ return formattedMessageData;\r
+ }\r
+}
\ No newline at end of file