Reviewed IDE upload procedure for Leonardo bootloader

This commit is contained in:
Cristian Maglie 2012-02-24 17:30:29 +01:00
parent 9ec558ba8d
commit 60f8e10bf9
2 changed files with 66 additions and 73 deletions

View File

@ -117,7 +117,7 @@ public class Serial implements SerialPortEventListener {
} }
} catch (PortInUseException e) { } catch (PortInUseException e) {
throw new SerialException( throw new SerialException(
I18n.format(_("Serial port ''{0}'' already in use. Try quiting any programs that may be using it."), iname) I18n.format(_("Serial port ''{0}'' already in use. Try quitting any programs that may be using it."), iname)
); );
} catch (Exception e) { } catch (Exception e) {
throw new SerialException( throw new SerialException(
@ -553,10 +553,11 @@ public class Serial implements SerialPortEventListener {
* it may be because the DLL doesn't have its exec bit set. * it may be because the DLL doesn't have its exec bit set.
* Why the hell that'd be the case, who knows. * Why the hell that'd be the case, who knows.
*/ */
static public String[] list() { static public List<String> list() {
Vector list = new Vector(); List<String> list = new ArrayList<String>();
try { try {
//System.err.println("trying"); //System.err.println("trying");
@SuppressWarnings("unchecked")
Enumeration portList = CommPortIdentifier.getPortIdentifiers(); Enumeration portList = CommPortIdentifier.getPortIdentifiers();
//System.err.println("got port list"); //System.err.println("got port list");
while (portList.hasMoreElements()) { while (portList.hasMoreElements()) {
@ -566,7 +567,7 @@ public class Serial implements SerialPortEventListener {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
String name = portId.getName(); String name = portId.getName();
list.addElement(name); list.add(name);
} }
} }
@ -579,9 +580,7 @@ public class Serial implements SerialPortEventListener {
errorMessage("ports", e); errorMessage("ports", e);
} }
//System.err.println("move out"); //System.err.println("move out");
String outgoing[] = new String[list.size()]; return list;
list.copyInto(outgoing);
return outgoing;
} }

View File

@ -77,75 +77,69 @@ public class AvrdudeUploader extends Uploader {
if (protocol.equals("stk500")) if (protocol.equals("stk500"))
protocol = "stk500v1"; protocol = "stk500v1";
// need to do a little dance for Leonardo and derivatives: String uploadPort = Preferences.get("serial.port");
// open then close the port at the magic baudrate (usually 1200 bps) first to signal to the
// sketch that it should reset into bootloader. after doing this wait a moment for the // need to do a little dance for Leonardo and derivatives:
// bootloader to enumerate. On Windows, also must deal with the fact that the COM port number // open then close the port at the magic baudrate (usually 1200 bps) first
// changes from bootloader to sketch. // to signal to the sketch that it should reset into bootloader. after doing
String leonardoUploadPort = null; // this wait a moment for the bootloader to enumerate. On Windows, also must
if (boardPreferences.get("bootloader.path").equals("caterina_LUFA")) { // deal with the fact that the COM port number changes from bootloader to
try { // sketch.
long startTime = System.currentTimeMillis(); if (boardPreferences.get("bootloader.path").equals("caterina_LUFA")) {
String portsBeforeReenum[] = Serial.list(); String caterinaUploadPort = null;
Serial.touchPort(Preferences.get("serial.port"), 1200); try {
if (Base.isWindows()) { // Toggle 1200 bps on selected serial port to force board reset.
// Windows has a complicated relationship with CDC devices. Have to deal with List<String> before = Serial.list();
// devices being slow to disconnect, slow to connect, and the fact that COM numbers if (before.contains(uploadPort)) {
// change from bootloader to sketch. To find the bootloader port we scan the list if (verbose)
// of reported ports continuously, waiting for the selected port to disappear, then System.out
// waiting for a new port to appear. Have to have long delays between calls to .println(_("Forcing reset using 1200bps open/close on port ")
// Serial.list() on Windows otherwise rxtx causes a bluescreen error. + uploadPort);
Serial.touchPort(uploadPort, 1200);
// Wait for the port to disappear from the list... }
long timeout = 0;
while (true == Arrays.asList(Serial.list()).contains(Preferences.get("serial.port")) && ((timeout = (System.currentTimeMillis() - startTime)) < 4000)) { // Wait for a port to appear on the list
Thread.sleep(1000); long timeout = System.currentTimeMillis() + 10000;
} while (System.currentTimeMillis() < timeout) {
System.out.println("first timeout: " + timeout); List<String> now = Serial.list();
List<String> diff = new ArrayList<String>(now);
Thread.sleep(1000); diff.removeAll(before);
System.out.print("{");
// ...and wait for a port, any port to appear. for (String p : before)
while ((portsBeforeReenum.length != Serial.list().length) && ((timeout = (System.currentTimeMillis() - startTime)) < 8000)) { System.out.print(p+",");
Thread.sleep(1000); System.out.print("} / {");
} for (String p : now)
System.out.println("second timeout: " + timeout); System.out.print(p+",");
System.out.print("} => {");
// Figure out which port is new. for (String p : diff)
String portsAfterReenum[] = Serial.list(); System.out.print(p+",");
for (String port : portsAfterReenum) { System.out.println("}");
if (!Arrays.asList(portsBeforeReenum).contains(port)) if (diff.size() > 0) {
leonardoUploadPort = port; caterinaUploadPort = diff.get(0);
} System.out.println("found leo: " + caterinaUploadPort);
System.out.println("found leo: " + leonardoUploadPort); break;
} else { }
// Reenumeration is much faster and less complicated on *nix:
// After touching the port wait for it to disappear (timeout on this operation in // Keep track of port that disappears
// case the port is either not a Leonardo, is a Leonardo with no sketch loaded, before = now;
// or is a Leonardo that has already been manually reset). Then wait for the same Thread.sleep(500);
// port to reappear in the list and proceed. }
// Wait for the port to disappear from the list... if (caterinaUploadPort == null)
while (true == Arrays.asList(Serial.list()).contains(Preferences.get("serial.port")) && (System.currentTimeMillis() - startTime < 4000)) { // Something happened while detecting port
Thread.sleep(10); return false;
}
// ...and wait for the same-named port to come back. uploadPort = caterinaUploadPort;
while (false == Arrays.asList(Serial.list()).contains(Preferences.get("serial.port")) && (System.currentTimeMillis() - startTime < 8000)) { } catch (SerialException ex) {
Thread.sleep(10); return false;
} } catch (InterruptedException ex) {
} return false;
} catch (SerialException ex) { }
} catch (InterruptedException ex) { }
} }
commandDownloader.add("-c" + protocol); commandDownloader.add("-c" + protocol);
if (null == leonardoUploadPort) { commandDownloader.add("-P" + (Base.isWindows() ? "\\\\.\\" : "")
commandDownloader.add( + uploadPort);
"-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
} else {
commandDownloader.add(
"-P" + (Base.isWindows() ? "\\\\.\\" : "") + leonardoUploadPort);
}
commandDownloader.add( commandDownloader.add(
"-b" + Integer.parseInt(boardPreferences.get("upload.speed"))); "-b" + Integer.parseInt(boardPreferences.get("upload.speed")));
commandDownloader.add("-D"); // don't erase commandDownloader.add("-D"); // don't erase