import re
import shutil
import json
+import serial.tools.list_ports
class FatalError(RuntimeError):
"""
def _get_esptool_args(args):
esptool_path = os.path.join(os.environ["IDF_PATH"], "components/esptool_py/esptool/esptool.py")
+ if args.port is None:
+ args.port = get_default_serial_port()
result = [ PYTHON, esptool_path ]
- if args.port is not None:
- result += [ "-p", args.port ]
+ result += [ "-p", args.port ]
result += [ "-b", str(args.baud) ]
return result
"""
Run idf_monitor.py to watch build output
"""
+ if args.port is None:
+ args.port = get_default_serial_port()
desc_path = os.path.join(args.build_dir, "project_description.json")
if not os.path.exists(desc_path):
_ensure_build_directory(args)
else: # flashing the whole project
cmd = " ".join(flasher_args["write_flash_args"]) + " "
flash_items = sorted(((o,f) for (o,f) in flasher_args["flash_files"].items() if len(o) > 0),
- key = lambda (o,_): int(o, 0))
+ key = lambda x: int(x[0], 0))
for o,f in flash_items:
cmd += o + " " + flasher_path(f) + " "
result.append(a)
return result
+def get_default_serial_port():
+ """ Return a default serial port. esptool can do this (smarter), but it can create
+ inconsistencies where esptool.py uses one port and idf_monitor uses another.
+
+ Same logic as esptool.py search order, reverse sort by name and choose the first port.
+ """
+ ports = list(reversed(sorted(
+ p.device for p in serial.tools.list_ports.comports() )))
+ try:
+ print ("Choosing default port %s (use '-p PORT' option to set a specific serial port)" % ports[0])
+ return ports[0]
+ except IndexError:
+ raise RuntimeError("No serial ports found. Connect a device, or use '-p PORT' option to set a specific port.")
+
+
def main():
if sys.version_info[0] != 2 or sys.version_info[1] != 7:
raise FatalError("ESP-IDF currently only supports Python 2.7, and this is Python %d.%d.%d. Search for 'Setting the Python Interpreter' in the ESP-IDF docs for some tips to handle this." % sys.version_info[:3])