diff --git a/app/src/processing/app/debug/AvrdudeUploader.java b/app/src/processing/app/debug/AvrdudeUploader.java index 7afec04b4..dbfdd9b88 100755 --- a/app/src/processing/app/debug/AvrdudeUploader.java +++ b/app/src/processing/app/debug/AvrdudeUploader.java @@ -30,6 +30,7 @@ import processing.app.Base; import processing.app.Preferences; import processing.app.Serial; import processing.app.SerialException; +import static processing.app.I18n._; import java.io.*; import java.util.*; @@ -63,36 +64,53 @@ public class AvrdudeUploader extends Uploader { return avrdude(params); } - return uploadViaBootloader(buildPath, className); + return uploadViaBootloader(buildPath, className); + } + + private static String selectLeonardoUploadPort() { + String names[] = Serial.list(); + String result = (String)JOptionPane.showInputDialog(null, processing.app.I18n.format(_("Please select the Leonardo upload port:")), "Select upload port", JOptionPane.PLAIN_MESSAGE, null, names, 0); + return result; } private boolean uploadViaBootloader(String buildPath, String className) - throws RunnerException, SerialException { + throws RunnerException, SerialException { Map boardPreferences = Base.getBoardPreferences(); List commandDownloader = new ArrayList(); String protocol = boardPreferences.get("upload.protocol"); // avrdude wants "stk500v1" to distinguish it from stk500v2 if (protocol.equals("stk500")) - protocol = "stk500v1"; - + protocol = "stk500v1"; + // need to do a little dance for Leonardo and derivatives: // 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 - // bootloader to enumerate + // bootloader to enumerate. On Windows, also must deal with the fact that the COM port number + // changes from bootloader to sketch. + String leonardoUploadPort = null; if (boardPreferences.get("bootloader.path").equals("caterina_LUFA")) { try { - Serial serial = new Serial(Integer.parseInt(boardPreferences.get("upload.speed"))); - serial.dispose(); - serial = null; - Thread.sleep(8000); + Serial.touchPort(Preferences.get("serial.port"), 1200); + Thread.sleep(8000); } catch (SerialException ex) { - } catch (InterruptedException ex) { } + } catch (InterruptedException ex) { } + + if (Base.isWindows()) { + leonardoUploadPort = selectLeonardoUploadPort(); + if (null == leonardoUploadPort) + return false; + } } commandDownloader.add("-c" + protocol); - commandDownloader.add( - "-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port")); + if (null == leonardoUploadPort) { + commandDownloader.add( + "-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port")); + } else { + commandDownloader.add( + "-P" + (Base.isWindows() ? "\\\\.\\" : "") + leonardoUploadPort); + } commandDownloader.add( "-b" + Integer.parseInt(boardPreferences.get("upload.speed"))); commandDownloader.add("-D"); // don't erase diff --git a/hardware/arduino/boards.txt b/hardware/arduino/boards.txt index 89035e690..7d25ab82b 100644 --- a/hardware/arduino/boards.txt +++ b/hardware/arduino/boards.txt @@ -149,7 +149,8 @@ mega.build.variant=mega leonardo.name=Arduino Leonardo leonardo.upload.protocol=avr109 leonardo.upload.maximum_size=28672 -leonardo.upload.speed=1200 +leonardo.upload.speed=57600 +leonardo.upload.disable_flushing=true leonardo.bootloader.low_fuses=0xde leonardo.bootloader.high_fuses=0xd8 leonardo.bootloader.extended_fuses=0xcb diff --git a/hardware/arduino/cores/arduino/CDC.cpp b/hardware/arduino/cores/arduino/CDC.cpp index 6dd1cbee9..deda5c08b 100644 --- a/hardware/arduino/cores/arduino/CDC.cpp +++ b/hardware/arduino/cores/arduino/CDC.cpp @@ -23,20 +23,6 @@ #if defined(USBCON) #ifdef CDC_ENABLED -void Reboot() -{ - USB.detach(); - cli(); - - // Reset the microcontroller to run the bootloader - wdt_enable(WDTO_15MS); - for (;;); -} - -// Define constants and variables for buffering incoming serial data. We're -// using a ring buffer (I think), in which head is the index of the location -// to which to write the next incoming character and tail is the index of the -// location from which to read. #if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 16 #else @@ -114,9 +100,14 @@ bool WEAK CDC_Setup(Setup& setup) if (CDC_SET_CONTROL_LINE_STATE == r) { - if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) // auto-reset is triggered when the port, already open at 1200 bps, is closed - Reboot(); _usbLineInfo.lineState = setup.wValueL; + // auto-reset into the bootloader is triggered when the port, already + // open at 1200 bps, is closed. this is the signal to start the watchdog + // with a relatively long period so it can finish housekeeping tasks + // like servicing endpoints before the sketch ends + if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { + wdt_enable(WDTO_2S); + } return true; } }