 89c837ee34
			
		
	
	
		89c837ee34
		
	
	
	
	
		
			
			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.
		
			
				
	
	
		
			178 lines
		
	
	
		
			No EOL
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			No EOL
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| 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;
 | |
| 	}
 | |
| } |