From 7af9f50426730dedc65afcf8881f27cf91b534b3 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 28 Dec 2014 20:41:21 +0200 Subject: [PATCH] Fix firmware uploading to Arduino Leonardo-based boards // Resolve #40 --- platformio/builder/scripts/atmelavr.py | 17 +++++++++--- platformio/builder/tools/platformio.py | 37 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/platformio/builder/scripts/atmelavr.py b/platformio/builder/scripts/atmelavr.py index 9fdc046086..2b2584a426 100644 --- a/platformio/builder/scripts/atmelavr.py +++ b/platformio/builder/scripts/atmelavr.py @@ -58,7 +58,6 @@ UPLOADER=join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude"), UPLOADERFLAGS=[ - "-V", # do not verify "-q", # suppress progress output "-D", # disable auto erase for flash memory "-p", "$BOARD_MCU", @@ -118,7 +117,19 @@ def rpi_sysgpio(path, value): rpi_sysgpio("/sys/class/gpio/gpio18/value", 0) rpi_sysgpio("/sys/class/gpio/unexport", 18) else: - return env.FlushSerialBuffer("$UPLOAD_PORT") + upload_options = env.get("BOARD_OPTIONS", {}).get("upload", {}) + + if not upload_options.get("disable_flushing", False): + env.FlushSerialBuffer("$UPLOAD_PORT") + + before_ports = [i['port'] for i in get_serialports()] + + if (upload_options.get("use_1200bps_touch", False) and + "UPLOAD_PORT" in env): + env.TouchSerialPort("$UPLOAD_PORT", 1200) + + if upload_options.get("wait_for_upload_port", False): + env.Replace(UPLOAD_PORT=env.WaitForNewSerialPort(before_ports)) CORELIBS = env.ProcessGeneral() @@ -174,7 +185,7 @@ def rpi_sysgpio(path, value): for item in get_serialports(): if "VID:PID" in item['hwid']: print "Auto-detected UPLOAD_PORT: %s" % item['port'] - env['UPLOAD_PORT'] = item['port'] + env.Replace(UPLOAD_PORT=item['port']) break if "UPLOAD_PORT" not in env: diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index 822600fbe3..1da60525a7 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -2,14 +2,17 @@ # See LICENSE for details. import atexit +import platform import re from os import getenv, listdir, remove, walk from os.path import basename, isdir, isfile, join from time import sleep -from SCons.Script import SConscript, SConscriptChdir +from SCons.Script import Exit, SConscript, SConscriptChdir from serial import Serial +from platformio.util import get_serialports + def ProcessGeneral(env): corelibs = [] @@ -187,6 +190,36 @@ def FlushSerialBuffer(env, port): s.close() +def TouchSerialPort(env, port, baudrate): + s = Serial(port=env.subst(port), baudrate=baudrate) + s.close() + if platform.system() != "Darwin": + sleep(0.3) + + +def WaitForNewSerialPort(env, before): + new_port = None + elapsed = 0 + while elapsed < 10: + now = [i['port'] for i in get_serialports()] + diff = list(set(now) - set(before)) + if diff: + new_port = diff[0] + break + + before = now + sleep(0.25) + elapsed += 0.25 + + if not new_port: + Exit("Error: Couldn't find a board on the selected port. " + "Check that you have the correct port selected. " + "If it is correct, try pressing the board's reset " + "button after initiating the upload.") + + return new_port + + def exists(_): return True @@ -202,4 +235,6 @@ def generate(env): env.AddMethod(VariantDirRecursive) env.AddMethod(ConvertInoToCpp) env.AddMethod(FlushSerialBuffer) + env.AddMethod(TouchSerialPort) + env.AddMethod(WaitForNewSerialPort) return env