1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-25 06:22:11 +03:00
Files
esp8266/app/src/processing/app/debug/AvrdudeUploader.java

287 lines
11 KiB
Java
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
AvrdudeUploader - uploader implementation using avrdude
Part of the Arduino project - http://www.arduino.cc/
Copyright (c) 2004-05
Hernando Barragan
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$Id$
*/
package processing.app.debug;
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.*;
import java.util.zip.*;
import javax.swing.*;
import gnu.io.*;
public class AvrdudeUploader extends Uploader {
public AvrdudeUploader() {
}
public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
throws RunnerException, SerialException {
this.verbose = verbose;
Map<String, String> boardPreferences = Base.getBoardPreferences();
// if no protocol is specified for this board, assume it lacks a
// bootloader and upload using the selected programmer.
if (usingProgrammer || boardPreferences.get("upload.protocol") == null) {
String programmer = Preferences.get("programmer");
Target target = Base.getTarget();
if (programmer.indexOf(":") != -1) {
target = Base.targetsTable.get(programmer.substring(0, programmer.indexOf(":")));
programmer = programmer.substring(programmer.indexOf(":") + 1);
}
Collection params = getProgrammerCommands(target, programmer);
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
return avrdude(params);
}
return uploadViaBootloader(buildPath, className);
}
private boolean uploadViaBootloader(String buildPath, String className)
throws RunnerException, SerialException {
Map<String, String> 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";
String uploadPort = Preferences.get("serial.port");
// 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. On Windows, also must
// deal with the fact that the COM port number changes from bootloader to
// sketch.
if (boardPreferences.get("bootloader.path").equals("caterina_LUFA")) {
String caterinaUploadPort = null;
try {
// Toggle 1200 bps on selected serial port to force board reset.
List<String> before = Serial.list();
if (before.contains(uploadPort)) {
if (verbose)
System.out
.println(_("Forcing reset using 1200bps open/close on port ")
+ uploadPort);
Serial.touchPort(uploadPort, 1200);
}
// Wait for a port to appear on the list
int elapsed = 0;
while (elapsed < 10000) {
List<String> now = Serial.list();
List<String> diff = new ArrayList<String>(now);
diff.removeAll(before);
System.out.print("{");
for (String p : before)
System.out.print(p+",");
System.out.print("} / {");
for (String p : now)
System.out.print(p+",");
System.out.print("} => {");
for (String p : diff)
System.out.print(p+",");
System.out.println("}");
if (diff.size() > 0) {
caterinaUploadPort = diff.get(0);
System.out.println("found leo: " + caterinaUploadPort);
break;
}
// Keep track of port that disappears
before = now;
Thread.sleep(250);
elapsed += 250;
// If after 5 seconds the selected port is active use that port
if (elapsed == 5000 && now.contains(uploadPort)) {
System.out.println("using selected port: " + uploadPort);
caterinaUploadPort = uploadPort;
break;
}
}
if (caterinaUploadPort == null)
// Something happened while detecting port
throw new RunnerException(
_("Couldnt find the selected board. Try pressing the reset button after initiating the upload."));
uploadPort = caterinaUploadPort;
} catch (SerialException e) {
throw new RunnerException(e.getMessage());
} catch (InterruptedException e) {
throw new RunnerException(e.getMessage());
}
}
commandDownloader.add("-c" + protocol);
commandDownloader.add("-P" + (Base.isWindows() ? "\\\\.\\" : "")
+ uploadPort);
commandDownloader.add(
"-b" + Integer.parseInt(boardPreferences.get("upload.speed")));
commandDownloader.add("-D"); // don't erase
if (!Preferences.getBoolean("upload.verify")) commandDownloader.add("-V"); // disable verify
commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
if (boardPreferences.get("upload.disable_flushing") == null ||
boardPreferences.get("upload.disable_flushing").toLowerCase().equals("false")) {
flushSerialBuffer();
}
return avrdude(commandDownloader);
}
public boolean burnBootloader() throws RunnerException {
String programmer = Preferences.get("programmer");
Target target = Base.getTarget();
if (programmer.indexOf(":") != -1) {
target = Base.targetsTable.get(programmer.substring(0, programmer.indexOf(":")));
programmer = programmer.substring(programmer.indexOf(":") + 1);
}
return burnBootloader(getProgrammerCommands(target, programmer));
}
private Collection getProgrammerCommands(Target target, String programmer) {
Map<String, String> programmerPreferences = target.getProgrammers().get(programmer);
List params = new ArrayList();
params.add("-c" + programmerPreferences.get("protocol"));
if ("usb".equals(programmerPreferences.get("communication"))) {
params.add("-Pusb");
} else if ("serial".equals(programmerPreferences.get("communication"))) {
params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
if (programmerPreferences.get("speed") != null) {
params.add("-b" + Integer.parseInt(programmerPreferences.get("speed")));
}
}
// XXX: add support for specifying the port address for parallel
// programmers, although avrdude has a default that works in most cases.
if (programmerPreferences.get("force") != null &&
programmerPreferences.get("force").toLowerCase().equals("true"))
params.add("-F");
if (programmerPreferences.get("delay") != null)
params.add("-i" + programmerPreferences.get("delay"));
return params;
}
protected boolean burnBootloader(Collection params)
throws RunnerException {
Map<String, String> boardPreferences = Base.getBoardPreferences();
List fuses = new ArrayList();
fuses.add("-e"); // erase the chip
if (boardPreferences.get("bootloader.unlock_bits") != null)
fuses.add("-Ulock:w:" + boardPreferences.get("bootloader.unlock_bits") + ":m");
if (boardPreferences.get("bootloader.extended_fuses") != null)
fuses.add("-Uefuse:w:" + boardPreferences.get("bootloader.extended_fuses") + ":m");
fuses.add("-Uhfuse:w:" + boardPreferences.get("bootloader.high_fuses") + ":m");
fuses.add("-Ulfuse:w:" + boardPreferences.get("bootloader.low_fuses") + ":m");
if (!avrdude(params, fuses))
return false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
Target t;
List bootloader = new ArrayList();
String bootloaderPath = boardPreferences.get("bootloader.path");
if (bootloaderPath != null) {
if (bootloaderPath.indexOf(':') == -1) {
t = Base.getTarget(); // the current target (associated with the board)
} else {
String targetName = bootloaderPath.substring(0, bootloaderPath.indexOf(':'));
t = Base.targetsTable.get(targetName);
bootloaderPath = bootloaderPath.substring(bootloaderPath.indexOf(':') + 1);
}
File bootloadersFile = new File(t.getFolder(), "bootloaders");
File bootloaderFile = new File(bootloadersFile, bootloaderPath);
bootloaderPath = bootloaderFile.getAbsolutePath();
bootloader.add("-Uflash:w:" + bootloaderPath + File.separator +
boardPreferences.get("bootloader.file") + ":i");
}
if (boardPreferences.get("bootloader.lock_bits") != null)
bootloader.add("-Ulock:w:" + boardPreferences.get("bootloader.lock_bits") + ":m");
if (bootloader.size() > 0)
return avrdude(params, bootloader);
return true;
}
public boolean avrdude(Collection p1, Collection p2) throws RunnerException {
ArrayList p = new ArrayList(p1);
p.addAll(p2);
return avrdude(p);
}
public boolean avrdude(Collection params) throws RunnerException {
List commandDownloader = new ArrayList();
if(Base.isLinux()) {
if ((new File(Base.getHardwarePath() + "/tools/" + "avrdude")).exists()) {
commandDownloader.add(Base.getHardwarePath() + "/tools/" + "avrdude");
commandDownloader.add("-C" + Base.getHardwarePath() + "/tools/avrdude.conf");
} else {
commandDownloader.add("avrdude");
}
}
else {
commandDownloader.add(Base.getHardwarePath() + "/tools/avr/bin/" + "avrdude");
commandDownloader.add("-C" + Base.getHardwarePath() + "/tools/avr/etc/avrdude.conf");
}
if (verbose || Preferences.getBoolean("upload.verbose")) {
commandDownloader.add("-v");
commandDownloader.add("-v");
commandDownloader.add("-v");
commandDownloader.add("-v");
} else {
commandDownloader.add("-q");
commandDownloader.add("-q");
}
commandDownloader.add("-p" + Base.getBoardPreferences().get("build.mcu"));
commandDownloader.addAll(params);
return executeUploadCommand(commandDownloader);
}
}