diff --git a/app/src/processing/app/debug/AvrdudeUploader.java b/app/src/processing/app/debug/AvrdudeUploader.java index 6270db6ac..d9ff99a43 100644 --- a/app/src/processing/app/debug/AvrdudeUploader.java +++ b/app/src/processing/app/debug/AvrdudeUploader.java @@ -35,57 +35,87 @@ import processing.app.Base; import processing.app.Preferences; import processing.app.SerialException; import processing.app.helpers.PreferencesMap; +import processing.app.helpers.StringReplacer; public class AvrdudeUploader extends Uploader { public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer) throws RunnerException, SerialException { - PreferencesMap boardPreferences = Base.getBoardPreferences(); + // FIXME: Preferences should be reorganized + PreferencesMap prefs = Preferences.getMap(); + prefs.putAll(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"); - TargetPlatform targetPlatform = Base.getTargetPlatform(); + if (usingProgrammer || prefs.get("upload.protocol") == null) { + return uploadUsingProgrammer(buildPath, className); + } - if (programmer.contains(":")) { - String[] split = programmer.split(":", 2); - targetPlatform = Base.getTargetPlatform(split[0], Preferences - .get("target_platform")); - programmer = split[1]; + prefs.put("build.path", buildPath); + prefs.put("build.project_name", className); + + TargetPlatform targetPlatform = Base.getTargetPlatform(); + + prefs.putAll(targetPlatform.getTool(prefs.get("upload.tool"))); + if (verbose) + prefs.put("upload.verbose", prefs.get("upload.params.verbose")); + else + prefs.put("upload.verbose", prefs.get("upload.params.quiet")); + + String pattern = prefs.get("upload.pattern"); + try { + if (prefs.get("upload.disable_flushing") == null + || prefs.get("upload.disable_flushing").toLowerCase().equals("false")) { + flushSerialBuffer(); } - - Collection params = getProgrammerCommands(targetPlatform, programmer); - params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i"); - return avrdude(params); - } - return uploadViaBootloader(buildPath, className); + String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true); + return executeUploadCommand(cmd); + } catch (Exception e) { + throw new RunnerException(e); + } } - - private boolean uploadViaBootloader(String buildPath, String className) - throws RunnerException, SerialException { - PreferencesMap 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"; - commandDownloader.add("-c" + protocol); - commandDownloader.add( - "-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port")); - commandDownloader.add( - "-b" + Integer.parseInt(boardPreferences.get("upload.speed"))); - commandDownloader.add("-D"); // don't erase - 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(); + public boolean uploadUsingProgrammer(String buildPath, String className) + throws RunnerException { + + String programmer = Preferences.get("programmer"); + TargetPlatform targetPlatform = Base.getTargetPlatform(); + if (programmer.contains(":")) { + String[] split = programmer.split(":", 2); + targetPlatform = Base.getTargetPlatform(split[0], Preferences + .get("target_platform")); + programmer = split[1]; } - return avrdude(commandDownloader); + PreferencesMap prefs = Preferences.getMap(); + prefs.putAll(Base.getBoardPreferences()); + prefs.putAll(targetPlatform.getProgrammers().get(programmer)); + + prefs.put("build.path", buildPath); + prefs.put("build.project_name", className); + + PreferencesMap programmers = targetPlatform.getPreferences() + .createSubTree("programmers"); + prefs.putAll(programmers.createSubTree(prefs.get("program.tool"))); + + if (verbose) + prefs.put("program.verbose", prefs.get("program.params.verbose")); + else + prefs.put("program.verbose", prefs.get("program.params.quiet")); + + String pattern = prefs.get("program.pattern"); + try { + if (prefs.get("program.disable_flushing") == null + || prefs.get("program.disable_flushing").toLowerCase().equals("false")) { + flushSerialBuffer(); + } + + String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true); + return executeUploadCommand(cmd); + } catch (Exception e) { + throw new RunnerException(e); + } } public boolean burnBootloader() throws RunnerException { @@ -108,14 +138,15 @@ public class AvrdudeUploader extends Uploader { 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")); + params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + + Preferences.get("serial.port")); if (programmerPreferences.get("speed") != null) { - params.add("-b" + Integer.parseInt(programmerPreferences.get("speed"))); + 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"); @@ -129,7 +160,7 @@ public class AvrdudeUploader extends Uploader { protected boolean burnBootloader(Collection params) throws RunnerException { PreferencesMap boardPreferences = Base.getBoardPreferences(); - List fuses = new ArrayList(); + List fuses = new ArrayList(params); fuses.add("-e"); // erase the chip if (boardPreferences.get("bootloader.unlock_bits") != null) fuses.add("-Ulock:w:" + boardPreferences.get("bootloader.unlock_bits") + ":m"); @@ -138,7 +169,7 @@ public class AvrdudeUploader extends Uploader { fuses.add("-Uhfuse:w:" + boardPreferences.get("bootloader.high_fuses") + ":m"); fuses.add("-Ulfuse:w:" + boardPreferences.get("bootloader.low_fuses") + ":m"); - if (!avrdude(params, fuses)) + if (!avrdude(fuses)) return false; try { @@ -170,18 +201,14 @@ public class AvrdudeUploader extends Uploader { 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); + if (bootloader.size() > 0) { + params.addAll(bootloader); + return avrdude(params); + } return true; } - public boolean avrdude(Collection p1, Collection p2) throws RunnerException { - List p = new ArrayList(p1); - p.addAll(p2); - return avrdude(p); - } - public boolean avrdude(Collection params) throws RunnerException { List commandDownloader = new ArrayList(); diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index d5fd231d6..fa71913ea 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -50,7 +50,6 @@ public class Compiler implements MessageConsumer { private Sketch sketch; - private String primaryClassName; private List objectFiles; private PreferencesMap prefs; @@ -71,86 +70,17 @@ public class Compiler implements MessageConsumer { String _primaryClassName, boolean _verbose) throws RunnerException { sketch = _sketch; - primaryClassName = _primaryClassName; verbose = _verbose; objectFiles = new ArrayList(); - TargetPlatform targetPlatform = Base.getTargetPlatform(); - - // Merge all the global preference configuration in order of priority - prefs = new PreferencesMap(); - prefs.putAll(Preferences.getMap()); - prefs.putAll(targetPlatform.getPreferences()); - prefs.putAll(Base.getBoardPreferences()); - for (String k : prefs.keySet()) { - if (prefs.get(k) == null) - prefs.put(k, ""); - } - - prefs.put("build.path", _buildPath); - - String idePath = System.getProperty("user.dir"); - if (Base.isMacOS()) - idePath += "/Arduino.app/Contents/Resources/Java"; - prefs.put("ide.path", idePath); - prefs.put("ide.version", "" + Base.REVISION); - - if (!prefs.containsKey("compiler.path")) - prefs.put("compiler.path", Base.getAvrBasePath()); - - // Core folder - String core = prefs.get("build.core"); - if (core == null) { - RunnerException re = new RunnerException( - _("No board selected; please choose a board from the Tools > Board menu.")); - re.hideStackTrace(); - throw re; - } - TargetPlatform tp; - if (!core.contains(":")) { - tp = targetPlatform; - } else { - String[] split = core.split(":", 2); - tp = Base.getTargetPlatform(split[0], Preferences.get("target_platform")); - core = split[1]; - } - File coreFolder = new File(tp.getFolder(), "cores"); - coreFolder = new File(coreFolder, core); - prefs.put("build.core.path", coreFolder.getAbsolutePath()); - - // System Folder - File systemFolder = targetPlatform.getFolder(); - systemFolder = new File(systemFolder, "system"); - prefs.put("build.system.path", systemFolder.getAbsolutePath()); - - // Variant Folder - String variantPath; - String variant = prefs.get("build.variant"); - if (variant != null) { - TargetPlatform t; - if (!variant.contains(":")) { - t = targetPlatform; - } else { - String[] split = variant.split(":", 2); - t = Base.getTargetPlatform(split[0], Preferences - .get("target_platform")); - variant = split[1]; - } - File variantFolder = new File(t.getFolder(), "variants"); - variantFolder = new File(variantFolder, variant); - variantPath = variantFolder.getAbsolutePath(); - prefs.put("build.variant.path", variantPath); - } else { - variantPath = null; - prefs.put("build.variant.path", ""); - } + prefs = createBuildPreferences(_buildPath, _primaryClassName); // 0. include paths for core + all libraries sketch.setCompilingProgress(20); List includePaths = new ArrayList(); includePaths.add(prefs.get("build.core.path")); - if (variantPath != null) - includePaths.add(variantPath); + if (!prefs.get("build.variant.path").isEmpty()) + includePaths.add(prefs.get("build.variant.path")); for (File file : sketch.getImportedLibraries()) includePaths.add(file.getPath()); @@ -184,6 +114,74 @@ public class Compiler implements MessageConsumer { return true; } + private PreferencesMap createBuildPreferences(String _buildPath, + String _primaryClassName) + throws RunnerException { + TargetPlatform targetPlatform = Base.getTargetPlatform(); + + // Merge all the global preference configuration in order of priority + PreferencesMap p = new PreferencesMap(); + p.putAll(Preferences.getMap()); + p.putAll(targetPlatform.getPreferences()); + p.putAll(Base.getBoardPreferences()); + for (String k : p.keySet()) { + if (p.get(k) == null) + p.put(k, ""); + } + + p.put("build.path", _buildPath); + p.put("build.project_name", _primaryClassName); + + if (!p.containsKey("compiler.path")) + p.put("compiler.path", Base.getAvrBasePath()); + + // Core folder + String core = p.get("build.core"); + if (core == null) { + RunnerException re = new RunnerException( + _("No board selected; please choose a board from the Tools > Board menu.")); + re.hideStackTrace(); + throw re; + } + TargetPlatform tp; + if (!core.contains(":")) { + tp = targetPlatform; + } else { + String[] split = core.split(":", 2); + tp = Base.getTargetPlatform(split[0], Preferences.get("target_platform")); + core = split[1]; + } + File coreFolder = new File(tp.getFolder(), "cores"); + coreFolder = new File(coreFolder, core); + p.put("build.core.path", coreFolder.getAbsolutePath()); + + // System Folder + File systemFolder = targetPlatform.getFolder(); + systemFolder = new File(systemFolder, "system"); + p.put("build.system.path", systemFolder.getAbsolutePath()); + + // Variant Folder + String variant = p.get("build.variant"); + if (variant != null) { + TargetPlatform t; + if (!variant.contains(":")) { + t = targetPlatform; + } else { + String[] split = variant.split(":", 2); + t = Base + .getTargetPlatform(split[0], Preferences.get("target_platform")); + variant = split[1]; + } + File variantFolder = new File(t.getFolder(), "variants"); + variantFolder = new File(variantFolder, variant); + p.put("build.variant.path", variantFolder.getAbsolutePath()); + } else { + p.put("build.variant.path", ""); + } + + return p; + } + private List compileFiles(String outputPath, File sourcePath, boolean recurse, List includePaths) throws RunnerException { @@ -640,7 +638,6 @@ public class Compiler implements MessageConsumer { dict.put("compiler.c.elf.flags", dict .get("compiler.c.elf.flags" + optRelax)); dict.put("archive_file", "core.a"); - dict.put("project_name", primaryClassName); dict.put("object_files", objectFileList); dict.put("ide_version", "" + Base.REVISION); @@ -657,7 +654,6 @@ public class Compiler implements MessageConsumer { // 5. extract EEPROM data (from EEMEM directive) to .eep file. void compileEep(List includePaths) throws RunnerException { PreferencesMap dict = new PreferencesMap(prefs); - dict.put("project_name", primaryClassName); dict.put("ide_version", "" + Base.REVISION); String[] cmdArray; @@ -673,7 +669,6 @@ public class Compiler implements MessageConsumer { // 6. build the .hex file void compileHex(List includePaths) throws RunnerException { PreferencesMap dict = new PreferencesMap(prefs); - dict.put("project_name", primaryClassName); dict.put("ide_version", "" + Base.REVISION); String[] cmdArray; diff --git a/app/src/processing/app/debug/TargetPlatform.java b/app/src/processing/app/debug/TargetPlatform.java index 39ccb93f9..5abc5fcd4 100644 --- a/app/src/processing/app/debug/TargetPlatform.java +++ b/app/src/processing/app/debug/TargetPlatform.java @@ -92,6 +92,10 @@ public class TargetPlatform { return programmers; } + public PreferencesMap getTool(String tool) { + return getPreferences().createSubTree("tools").createSubTree(tool); + } + public PreferencesMap getPreferences() { return preferences; } diff --git a/app/src/processing/app/debug/Uploader.java b/app/src/processing/app/debug/Uploader.java index 245e43bfd..0e79871a3 100644 --- a/app/src/processing/app/debug/Uploader.java +++ b/app/src/processing/app/debug/Uploader.java @@ -26,26 +26,17 @@ package processing.app.debug; -import processing.app.Base; +import static processing.app.I18n._; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; + +import processing.app.I18n; import processing.app.Preferences; import processing.app.Serial; import processing.app.SerialException; import processing.app.SerialNotFoundException; -import processing.app.I18n; -import static processing.app.I18n._; - -import java.io.*; -import java.util.*; -import java.util.zip.*; -import javax.swing.*; -//#ifndef RXTX -//import javax.comm.*; -//#else -// rxtx uses package gnu.io, but all the class names -// are the same as those used by javax.comm -import gnu.io.*; -//#endif - public abstract class Uploader implements MessageConsumer { static final String BUGS_URL = @@ -54,18 +45,12 @@ public abstract class Uploader implements MessageConsumer { I18n.format(_("Compiler error, please submit this code to {0}"), BUGS_URL); RunnerException exception; - //PdePreferences preferences; - //Serial serialPort; static InputStream serialInput; static OutputStream serialOutput; - //int serial; // last byte of data received boolean verbose; - public Uploader() { - } - public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer) throws RunnerException, SerialException; @@ -75,9 +60,8 @@ public abstract class Uploader implements MessageConsumer { // Cleanup the serial buffer try { Serial serialPort = new Serial(); - byte[] readBuffer; while(serialPort.available() > 0) { - readBuffer = serialPort.readBytes(); + serialPort.readBytes(); try { Thread.sleep(100); } catch (InterruptedException e) {} @@ -102,7 +86,14 @@ public abstract class Uploader implements MessageConsumer { } } - protected boolean executeUploadCommand(Collection commandDownloader) + protected boolean executeUploadCommand(Collection commandDownloader) + throws RunnerException { + String[] commandArray = new String[commandDownloader.size()]; + commandDownloader.toArray(commandArray); + return executeUploadCommand(commandArray); + } + + protected boolean executeUploadCommand(String commandArray[]) throws RunnerException { firstErrorFound = false; // haven't found any errors yet @@ -110,17 +101,12 @@ public abstract class Uploader implements MessageConsumer { notFoundError = false; int result=0; // pre-initialized to quiet a bogus warning from jikes - String userdir = System.getProperty("user.dir") + File.separator; - try { - String[] commandArray = new String[commandDownloader.size()]; - commandDownloader.toArray(commandArray); - - if (verbose || Preferences.getBoolean("upload.verbose")) { for(int i = 0; i < commandArray.length; i++) { System.out.print(commandArray[i] + " "); } System.out.println(); + if (verbose || Preferences.getBoolean("upload.verbose")) { } Process process = Runtime.getRuntime().exec(commandArray); new MessageSiphon(process.getInputStream(), this); diff --git a/hardware/arduino/avr/boards.txt b/hardware/arduino/avr/boards.txt index c9c68d0ba..32063cbd7 100644 --- a/hardware/arduino/avr/boards.txt +++ b/hardware/arduino/avr/boards.txt @@ -1,6 +1,7 @@ ############################################################## uno.name=Arduino Uno +uno.upload.tool=avrdude uno.upload.protocol=arduino uno.upload.maximum_size=32256 uno.upload.speed=115200 @@ -175,7 +176,7 @@ mega.build.variant=mega ############################################################## mini328.name=Arduino Mini w/ ATmega328 -mini328.upload.protocol=stk500 +mini328.upload.protocol=stk500v1 mini328.upload.maximum_size=28672 mini328.upload.speed=115200 @@ -452,3 +453,4 @@ atmega8.build.mcu=atmega8 atmega8.build.f_cpu=16000000L atmega8.build.core=arduino atmega8.build.variant=standard + diff --git a/hardware/arduino/avr/platform.txt b/hardware/arduino/avr/platform.txt index fa3fdc391..59e2d16fb 100644 --- a/hardware/arduino/avr/platform.txt +++ b/hardware/arduino/avr/platform.txt @@ -26,22 +26,56 @@ compiler.upload.flags= # -------------------- ## Compile c files -recipe.c.o.pattern={compiler.path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide.version} {includes} {source_file} -o {object_file} +recipe.c.o.pattern={compiler.path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file} ## Compile c++ files -recipe.cpp.o.pattern={compiler.path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide.version} {includes} {source_file} -o {object_file} +recipe.cpp.o.pattern={compiler.path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file} ## Create archives recipe.ar.pattern={compiler.path}{compiler.ar.cmd} {compiler.ar.flags} {build.path}/{archive_file} {object_file} ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern={compiler.path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build.path}/{project_name}.elf {object_files} {build.path}/{archive_file} -L{build.path} -lm +recipe.c.combine.pattern={compiler.path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build.path}/{build.project_name}.elf {object_files} {build.path}/{archive_file} -L{build.path} -lm ## Create eeprom -recipe.objcopy.eep.pattern={compiler.path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build.path}/{project_name}.elf {build.path}/{project_name}.eep +recipe.objcopy.eep.pattern={compiler.path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.eep ## Create hex -recipe.objcopy.hex.pattern={compiler.path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build.path}/{project_name}.elf {build.path}/{project_name}.hex +recipe.objcopy.hex.pattern={compiler.path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.hex +# AVR Uploader/Programmers tools +# ------------------- + +tools.avrdude.upload.cmd=avrdude +tools.avrdude.upload.path={runtime.ide.path}/hardware/tools +tools.avrdude.upload.config.path={upload.path}/avrdude.conf +tools.avrdude.upload.params.verbose=-v -v -v -v +tools.avrdude.upload.params.quiet=-q -q +tools.avrdude.upload.pattern={upload.path}/{upload.cmd} -C{upload.config.path} {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D -Uflash:w:{build.path}/{build.project_name}.hex:i + +# /home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude +# -C/home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude.conf +# -q -q +# -patmega328p +# -carduino +# -P/dev/ttyACM0 +# -b115200 +# -D +# -Uflash:w:/tmp/build366783256629686367.tmp/Blink.cpp.hex:i + +tools.avrdude.program.cmd=avrdude +tools.avrdude.program.path={runtime.ide.path}/hardware/tools +tools.avrdude.program.config.path={program.path}/avrdude.conf +tools.avrdude.program.params.verbose=-v -v -v -v +tools.avrdude.program.params.quiet=-q -q +tools.avrdude.program.pattern={program.path}/{program.cmd} -C{program.config.path} {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -Uflash:w:{build.path}/{build.project_name}.hex:i + +# /home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude +# -C/home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude.conf +# -q -q +# -patmega328p +# -cusbasp +# -Pusb +# -Uflash:w:/tmp/build8190214930979711138.tmp/Blink.cpp.hex:i diff --git a/hardware/arduino/avr/programmers.txt b/hardware/arduino/avr/programmers.txt index 02457d908..a05519378 100644 --- a/hardware/arduino/avr/programmers.txt +++ b/hardware/arduino/avr/programmers.txt @@ -1,24 +1,41 @@ avrisp.name=AVR ISP avrisp.communication=serial avrisp.protocol=stk500v1 +avrisp.program.protocol=stk500v1 +avrisp.program.tool=avrdude +avrisp.program.extra_params=-P{serial.port} avrispmkii.name=AVRISP mkII avrispmkii.communication=usb avrispmkii.protocol=stk500v2 +avrispmkii.program.protocol=stk500v2 +avrispmkii.program.tool=avrdude +avrispmkii.program.extra_params=-Pusb usbtinyisp.name=USBtinyISP usbtinyisp.protocol=usbtiny +usbtinyisp.program.tool=avrdude +usbtinyisp.program.extra_params= usbasp.name=USBasp usbasp.communication=usb usbasp.protocol=usbasp +usbasp.program.protocol=usbasp +usbasp.program.tool=avrdude +usbasp.program.extra_params=-Pusb parallel.name=Parallel Programmer parallel.protocol=dapa parallel.force=true # parallel.delay=200 +parallel.program.tool=avrdude +parallel.program.extra_params= arduinoisp.name=Arduino as ISP arduinoisp.communication=serial arduinoisp.protocol=stk500v1 arduinoisp.speed=9600 +arduinoisp.program.protocol=stk500v1 +arduinoisp.program.speed=9600 +arduinoisp.program.tool=avrdude +arduinoisp.program.extra_params=-P{serial.port} -b{program.speed}