-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