1 import javax
.sound
.midi
.*;
2 import javax
.sound
.midi
.MidiMessage
.*;
3 import java
.io
.RandomAccessFile
;
7 private static final int MIDI_CONTROL_CHANNEL
= 9;
8 private static final int MIDI_DATA_CHANNEL
= 0;
10 private static final int CONTROL_DEVICE_READY
= 0xD1;
11 private static final int CONTROL_ENTER_PROG_MODE
= 0xDC;
12 private static final int CONTROL_LEAVE_PROG_MODE
= 0xDF;
13 private static final int CONTROL_GET_PAGE_SIZE
= 0x01;
15 public static void main(String
[] args
)
19 System
.out
.println("BIN2BOOT - USB-MIDI bootloader");
20 System
.out
.println(" Usage: java BIN2BOOT {input}.bin");
23 RandomAccessFile inFile
= null
;
27 inFile
= new RandomAccessFile(args
[0], "r");
31 System
.out
.println("Could not open input file!");
35 MidiDevice currDevice
= null
;
36 Receiver midiOut
= null
;
37 Transmitter midiIn
= null
;
38 MIDIMessageReceiver midiInMessages
= new MIDIMessageReceiver();
42 MidiDevice
.Info
[] infos
= MidiSystem
.getMidiDeviceInfo();
44 for (MidiDevice
.Info info
: infos
)
46 currDevice
= MidiSystem
.getMidiDevice(info
);
48 if (!(currDevice
instanceof Sequencer
) && !(currDevice
instanceof Synthesizer
))
50 if (info
.getName().indexOf("LUFA") == -1)
53 System
.out
.println(" MIDI Device: " + info
.getName());
57 if (currDevice
.getMaxReceivers() != 0)
59 midiOut
= currDevice
.getReceiver();
63 if (currDevice
.getMaxTransmitters() != 0)
65 midiIn
= currDevice
.getTransmitter();
66 midiIn
.setReceiver(midiInMessages
);
71 if ((midiOut
== null
) || (midiIn
== null
))
73 System
.out
.println("Could not find suitable MIDI device!");
79 System
.out
.println("Could not enumerate MIDI devices!");
83 System
.out
.println("PROGRAMMING FILE...");
85 ProgramFirmware(inFile
, midiOut
, midiInMessages
);
87 System
.out
.println("DONE.");
98 System
.out
.println("ERROR: Could not close open resources.");
102 private static void ProgramFirmware(RandomAccessFile inFile
, Receiver midiOut
, MIDIMessageReceiver midiInMessages
)
106 System
.out
.println("Entering Programming Mode...");
107 sendByteViaMIDI(midiOut
, MIDI_CONTROL_CHANNEL
, CONTROL_ENTER_PROG_MODE
);
112 messageData
= receiveByteViaMIDI(midiInMessages
);
114 while ((messageData
[0] != MIDI_CONTROL_CHANNEL
) && (messageData
[1] != CONTROL_DEVICE_READY
));
116 System
.out
.println("Getting Page Size...");
117 sendByteViaMIDI(midiOut
, MIDI_CONTROL_CHANNEL
, CONTROL_GET_PAGE_SIZE
);
119 int nextByte
= inFile
.read();
120 while (nextByte
!= -1)
122 sendByteViaMIDI(midiOut
, 9, nextByte
);
124 if ((inFile
.getFilePointer() % (inFile
.length() / 100)) == 0)
125 System
.out
.println(" LOADING: " + (int)(inFile
.getFilePointer() / (inFile
.length() / 100.0)) + "%...");
127 nextByte
= inFile
.read();
130 sendByteViaMIDI(midiOut
, MIDI_CONTROL_CHANNEL
, CONTROL_LEAVE_PROG_MODE
);
134 System
.out
.println("ERROR: Could not send data to device.");
138 private static void sendByteViaMIDI(Receiver midiOut
, int channel
, int data
)
140 ShortMessage sendMessage
= new ShortMessage();
144 sendMessage
.setMessage(ShortMessage
.NOTE_ON
, channel
, (data
& 0x7F), (((data
& 0x80) == 0x80) ?
64 : 32));
145 midiOut
.send(sendMessage
, -1);
147 // try {Thread.sleep(1);} catch (Exception e) {}
149 sendMessage
.setMessage(ShortMessage
.NOTE_OFF
, channel
, (data
& 0x7F), (((data
& 0x80) == 0x80) ?
64 : 32));
150 midiOut
.send(sendMessage
, -1);
154 System
.out
.println("ERROR: Could not send MIDI note press.");
158 private static int[] receiveByteViaMIDI(MIDIMessageReceiver midiInReceiver
)
164 while (!(midiInReceiver
.hasReceived()));
165 messageData
= midiInReceiver
.receive().getMessage();
167 while ((messageData
[0] & 0xF0) != ShortMessage
.NOTE_ON
);
169 int channel
= (messageData
[0] & 0x0F);
170 int data
= (messageData
[1] | ((messageData
[2] == 64) ?
0x80 : 0x00));
172 int[] formattedMessageData
= new int[2];
173 formattedMessageData
[0] = channel
;
174 formattedMessageData
[1] = data
;
176 return formattedMessageData
;