package com.jopdesign.jopeclipse.internal.core; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.UnsupportedCommOperationException; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StreamTokenizer; import java.util.Map; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import com.jopdesign.jopeclipse.internal.ui.launchConfigurations.IJOPLaunchConfigurationConstants; public class JavaDown implements IApplication { protected static int SERIAL_PORT_BAUDRATE = 115200; protected static int SERIAL_PORT_DATABITS = SerialPort.DATABITS_8; protected static int SERIAL_PORT_PARITY = SerialPort.PARITY_NONE; protected static int SERIAL_PORT_STOPBITS = SerialPort.STOPBITS_1; /** Serial port timeout (in ms) */ protected static final int SERIAL_PORT_TIMEOUT = 2000; private String commPortId; private IPath jopFile; private IProgressMonitor progressMonitor; private boolean usb; public String getCommPortId() { return commPortId; } public IProgressMonitor getProgressMonitor() { return progressMonitor; } public void run(IProgressMonitor monitor) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, FileNotFoundException, IOException { final CommPortIdentifier commPortId = CommPortIdentifier .getPortIdentifier(this.commPortId); final SerialPort serialPort = openSerialPort(commPortId); download(jopFile, serialPort, usb, monitor); serialPort.close(); } public void setCommPortId(String commPortId) { this.commPortId = commPortId; } public void setJopFile(IPath jopFile) { this.jopFile = jopFile; } public void setProgressMonitor(IProgressMonitor progressMonitor) { this.progressMonitor = progressMonitor; } public Object start(IApplicationContext context) throws Exception { Map contextArguments = context.getArguments(); return contextArguments.get(IApplicationContext.APPLICATION_ARGS); } public void stop() { // TODO Auto-generated method stub } public void useUSB(boolean useUSB) { usb = useUSB; } /** * Downloads a JOPized file to JOP * * @param file * @param serialPort * @param usb * @param monitor * @throws FileNotFoundException * @throws IOException */ private void download(IPath file, SerialPort serialPort, boolean usb, IProgressMonitor monitor) throws FileNotFoundException, IOException { OutputStream serialOut = serialPort.getOutputStream(); InputStream serialIn = serialPort.getInputStream(); FileReader fileIn = new FileReader(file.toFile()); StreamTokenizer tok = new StreamTokenizer(fileIn); tok.slashSlashComments(true); tok.whitespaceChars(',', ','); int numReplies = 0; // Replies to read back int nwords = 0; // Total number of words to process // FIXME debug serialOut = new FileOutputStream(file.addFileExtension(".down").toFile()); serialIn = new InputStream() { @Override public int read() throws IOException { return 0; } }; for (int numProcessedTokens = 0; tok.nextToken() != StreamTokenizer.TT_EOF; ++numProcessedTokens) { // Get the 32 bit word to be sent int word = (int) tok.nval; // Java code length at index 1 position in .jop if (numProcessedTokens == 1) { /*sysoutStream.println(word + " words of Java bytecode (" + (word / 256) + " KB)"); */ nwords = word; monitor.beginTask( IJOPLaunchConfigurationConstants.DOWNLOAD_TASK, nwords); } for (int i = 0; i < 4; i++) { byte b = (byte) (word >> ((3 - i) * 8)); serialOut.write(b); ++numReplies; if (!usb) { // TODO merge the two branches? if (numProcessedTokens == i) { // TODO check reply serialIn.read(); --numReplies; } else if (serialIn.available() != 0) { serialIn.read(); --numReplies; } } } monitor.worked(1); // So much work } // Finalize while (numReplies > 0) { serialIn.read(); --numReplies; } } /** * Opens and configures a serial port * * @param commPortId * @return * @throws NoSuchPortException if the identifier does not specify a serial port * @throws PortInUseException if the port is in use * @throws UnsupportedCommOperationException if the settings are not supported */ private SerialPort openSerialPort(CommPortIdentifier commPortId) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException { if (commPortId.getPortType() != CommPortIdentifier.PORT_SERIAL) { throw new gnu.io.NoSuchPortException(); } SerialPort serialPort = (SerialPort) commPortId.open( IJOPLaunchConfigurationConstants.COMM_PORT_OWNER_ID, SERIAL_PORT_TIMEOUT); serialPort.setSerialPortParams(SERIAL_PORT_BAUDRATE, SERIAL_PORT_DATABITS, SERIAL_PORT_STOPBITS, SERIAL_PORT_PARITY); return serialPort; } }