2016-05-26 19:43:36 +03:00
|
|
|
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
|
2015-11-18 17:16:17 +02:00
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
2015-03-04 21:21:10 +02:00
|
|
|
|
2015-11-30 01:11:57 +02:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2016-06-11 00:02:36 +03:00
|
|
|
from os import environ
|
2015-11-30 01:11:57 +02:00
|
|
|
from os.path import isfile, join
|
2016-06-04 00:23:33 +03:00
|
|
|
from platform import system
|
2015-03-13 00:02:31 +02:00
|
|
|
from shutil import copyfile
|
2015-03-04 21:21:10 +02:00
|
|
|
from time import sleep
|
|
|
|
|
2015-12-28 20:09:48 +02:00
|
|
|
from serial import Serial
|
2015-03-04 21:21:10 +02:00
|
|
|
|
2016-06-11 00:02:36 +03:00
|
|
|
from platformio import util
|
2015-12-28 20:35:56 +02:00
|
|
|
|
2015-03-04 21:21:10 +02:00
|
|
|
|
|
|
|
def FlushSerialBuffer(env, port):
|
|
|
|
s = Serial(env.subst(port))
|
|
|
|
s.flushInput()
|
|
|
|
s.setDTR(False)
|
|
|
|
s.setRTS(False)
|
|
|
|
sleep(0.1)
|
|
|
|
s.setDTR(True)
|
|
|
|
s.setRTS(True)
|
|
|
|
s.close()
|
|
|
|
|
|
|
|
|
|
|
|
def TouchSerialPort(env, port, baudrate):
|
2016-06-11 00:02:36 +03:00
|
|
|
if system() != "Windows":
|
2015-05-14 17:57:21 +03:00
|
|
|
try:
|
|
|
|
s = Serial(env.subst(port))
|
|
|
|
s.close()
|
2015-05-14 23:13:20 +02:00
|
|
|
except: # pylint: disable=W0702
|
2015-05-14 17:57:21 +03:00
|
|
|
pass
|
2015-03-04 21:21:10 +02:00
|
|
|
s = Serial(port=env.subst(port), baudrate=baudrate)
|
2015-03-18 23:17:39 +02:00
|
|
|
s.setDTR(False)
|
2015-03-04 21:21:10 +02:00
|
|
|
s.close()
|
2015-03-18 23:17:39 +02:00
|
|
|
sleep(0.4)
|
2015-03-04 21:21:10 +02:00
|
|
|
|
|
|
|
|
2016-06-03 00:42:52 +03:00
|
|
|
def WaitForNewSerialPort(env, before):
|
2016-06-03 01:29:18 +03:00
|
|
|
print "Waiting for the new upload port..."
|
2016-06-03 18:35:47 +03:00
|
|
|
prev_port = env.subst("$UPLOAD_PORT")
|
2015-03-04 21:21:10 +02:00
|
|
|
new_port = None
|
|
|
|
elapsed = 0
|
2016-06-11 23:35:29 +03:00
|
|
|
sleep(1)
|
2016-06-03 18:35:47 +03:00
|
|
|
while elapsed < 5 and new_port is None:
|
2016-06-11 00:02:36 +03:00
|
|
|
now = util.get_serialports()
|
2016-06-03 18:35:47 +03:00
|
|
|
for p in now:
|
|
|
|
if p not in before:
|
|
|
|
new_port = p['port']
|
|
|
|
break
|
2015-03-04 21:21:10 +02:00
|
|
|
before = now
|
|
|
|
sleep(0.25)
|
|
|
|
elapsed += 0.25
|
|
|
|
|
2016-06-03 18:35:47 +03:00
|
|
|
if not new_port:
|
|
|
|
for p in now:
|
|
|
|
if prev_port == p['port']:
|
|
|
|
new_port = p['port']
|
|
|
|
break
|
|
|
|
|
2015-03-04 21:21:10 +02:00
|
|
|
if not new_port:
|
2015-12-28 20:09:48 +02:00
|
|
|
env.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.")
|
2015-03-04 21:21:10 +02:00
|
|
|
|
|
|
|
return new_port
|
|
|
|
|
|
|
|
|
2016-06-11 15:12:27 +03:00
|
|
|
def AutodetectUploadPort(*args, **kwargs): # pylint: disable=unused-argument
|
|
|
|
env = args[0]
|
2016-06-11 15:39:06 +03:00
|
|
|
print "Looking for upload port/disk..."
|
2015-03-09 12:27:54 +02:00
|
|
|
|
2016-06-08 13:47:03 +03:00
|
|
|
def _look_for_mbed_disk():
|
2015-03-13 00:02:31 +02:00
|
|
|
msdlabels = ("mbed", "nucleo", "frdm")
|
2016-06-11 00:02:36 +03:00
|
|
|
for item in util.get_logicaldisks():
|
2015-03-13 00:02:31 +02:00
|
|
|
if (not item['name'] or
|
|
|
|
not any([l in item['name'].lower() for l in msdlabels])):
|
2015-03-09 12:27:54 +02:00
|
|
|
continue
|
2016-06-08 13:47:03 +03:00
|
|
|
return item['disk']
|
|
|
|
return None
|
2016-06-03 20:57:20 +03:00
|
|
|
|
2016-06-08 13:47:03 +03:00
|
|
|
def _look_for_serial_port():
|
|
|
|
port = None
|
2016-05-26 19:43:36 +03:00
|
|
|
board_hwids = []
|
|
|
|
if "BOARD" in env and "build.hwids" in env.BoardConfig():
|
|
|
|
board_hwids = env.BoardConfig().get("build.hwids")
|
2016-06-11 00:36:27 +03:00
|
|
|
for item in util.get_serialports():
|
2015-03-09 12:27:54 +02:00
|
|
|
if "VID:PID" not in item['hwid']:
|
|
|
|
continue
|
2016-06-08 13:47:03 +03:00
|
|
|
port = item['port']
|
2016-05-26 19:43:36 +03:00
|
|
|
for hwid in board_hwids:
|
|
|
|
hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
|
|
|
|
if hwid_str in item['hwid']:
|
2016-06-08 13:47:03 +03:00
|
|
|
return port
|
|
|
|
return port
|
2015-03-04 21:21:10 +02:00
|
|
|
|
2015-06-08 23:02:05 +03:00
|
|
|
if "UPLOAD_PORT" in env:
|
2016-06-11 15:39:06 +03:00
|
|
|
print env.subst("Manually specified: $UPLOAD_PORT")
|
2016-06-08 13:47:03 +03:00
|
|
|
return
|
|
|
|
|
|
|
|
if env.subst("$FRAMEWORK") == "mbed":
|
|
|
|
env.Replace(UPLOAD_PORT=_look_for_mbed_disk())
|
|
|
|
else:
|
|
|
|
if (system() == "Linux" and
|
|
|
|
not isfile("/etc/udev/99-platformio-udev.rules")):
|
2016-06-11 15:12:27 +03:00
|
|
|
print(
|
2016-06-08 13:47:03 +03:00
|
|
|
"\nWarning! Please install `99-platformio-udev.rules` and "
|
|
|
|
"check that your board's PID and VID are listed in the rules."
|
|
|
|
"\n https://raw.githubusercontent.com/platformio/platformio"
|
|
|
|
"/develop/scripts/99-platformio-udev.rules\n"
|
|
|
|
)
|
|
|
|
env.Replace(UPLOAD_PORT=_look_for_serial_port())
|
|
|
|
|
|
|
|
if env.subst("$UPLOAD_PORT"):
|
2016-06-11 15:39:06 +03:00
|
|
|
print env.subst("Auto-detected: $UPLOAD_PORT")
|
2015-06-08 23:02:05 +03:00
|
|
|
else:
|
2015-12-28 20:09:48 +02:00
|
|
|
env.Exit("Error: Please specify `upload_port` for environment or use "
|
|
|
|
"global `--upload-port` option.\n"
|
|
|
|
"For some development platforms this can be a USB flash "
|
|
|
|
"drive (i.e. /media/<user>/<device name>)\n")
|
2015-03-04 21:21:10 +02:00
|
|
|
|
|
|
|
|
2015-03-13 00:02:31 +02:00
|
|
|
def UploadToDisk(_, target, source, env): # pylint: disable=W0613,W0621
|
|
|
|
env.AutodetectUploadPort()
|
2016-06-01 23:33:15 +03:00
|
|
|
progname = env.subst("$PROGNAME")
|
2015-11-02 23:03:05 +02:00
|
|
|
for ext in ("bin", "hex"):
|
2016-06-01 23:33:15 +03:00
|
|
|
fpath = join(env.subst("$BUILD_DIR"), "%s.%s" % (progname, ext))
|
2015-11-02 23:03:05 +02:00
|
|
|
if not isfile(fpath):
|
|
|
|
continue
|
2016-06-01 23:33:15 +03:00
|
|
|
copyfile(fpath, join(
|
|
|
|
env.subst("$UPLOAD_PORT"), "%s.%s" % (progname, ext)))
|
2015-12-28 20:09:48 +02:00
|
|
|
print("Firmware has been successfully uploaded.\n"
|
|
|
|
"Please restart your board.")
|
2015-03-13 00:02:31 +02:00
|
|
|
|
|
|
|
|
2016-06-11 00:55:38 +03:00
|
|
|
def CheckUploadSize(_, target, source, env): # pylint: disable=W0613,W0621
|
2016-06-11 00:36:27 +03:00
|
|
|
if "BOARD" not in env:
|
|
|
|
return
|
|
|
|
max_size = int(env.BoardConfig().get("upload.maximum_size", 0))
|
2016-06-11 00:02:36 +03:00
|
|
|
if max_size == 0 or "SIZETOOL" not in env:
|
|
|
|
return
|
|
|
|
|
2016-06-11 15:39:06 +03:00
|
|
|
print "Check program size..."
|
2016-06-11 00:02:36 +03:00
|
|
|
sysenv = environ.copy()
|
|
|
|
sysenv['PATH'] = str(env['ENV']['PATH'])
|
2016-06-11 00:55:38 +03:00
|
|
|
cmd = [env.subst("$SIZETOOL"), "-B", str(source[0])]
|
2016-06-11 00:02:36 +03:00
|
|
|
result = util.exec_command(cmd, env=sysenv)
|
|
|
|
if result['returncode'] != 0:
|
|
|
|
return
|
2016-06-11 15:39:06 +03:00
|
|
|
print result['out'].strip()
|
2016-06-11 00:02:36 +03:00
|
|
|
|
|
|
|
line = result['out'].strip().splitlines()[1]
|
|
|
|
values = [v.strip() for v in line.split("\t")]
|
|
|
|
used_size = int(values[0]) + int(values[1])
|
|
|
|
|
|
|
|
if used_size > max_size:
|
|
|
|
env.Exit("Error: The program size (%d bytes) is greater "
|
|
|
|
"than maximum allowed (%s bytes)" % (used_size, max_size))
|
|
|
|
|
|
|
|
|
2015-03-04 21:21:10 +02:00
|
|
|
def exists(_):
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def generate(env):
|
|
|
|
env.AddMethod(FlushSerialBuffer)
|
|
|
|
env.AddMethod(TouchSerialPort)
|
|
|
|
env.AddMethod(WaitForNewSerialPort)
|
|
|
|
env.AddMethod(AutodetectUploadPort)
|
2015-03-13 00:02:31 +02:00
|
|
|
env.AddMethod(UploadToDisk)
|
2016-06-11 00:02:36 +03:00
|
|
|
env.AddMethod(CheckUploadSize)
|
2015-03-04 21:21:10 +02:00
|
|
|
return env
|