aboutsummaryrefslogtreecommitdiff
path: root/bin/ard-reset-arduino
diff options
context:
space:
mode:
Diffstat (limited to 'bin/ard-reset-arduino')
-rwxr-xr-xbin/ard-reset-arduino90
1 files changed, 89 insertions, 1 deletions
diff --git a/bin/ard-reset-arduino b/bin/ard-reset-arduino
index 1f2c7e9..d6f974f 100755
--- a/bin/ard-reset-arduino
+++ b/bin/ard-reset-arduino
@@ -2,6 +2,7 @@
from __future__ import print_function
import serial
+import serial.tools.list_ports
import os.path
import argparse
from time import sleep
@@ -13,13 +14,100 @@ except:
pyserial_version = 2 # less than 2.3
parser = argparse.ArgumentParser(description='Reset an Arduino')
+parser.add_argument('--zero', action='store_true', help='Reset Arduino Zero or similar Native USB to enter bootloader')
parser.add_argument('--caterina', action='store_true', help='Reset a Leonardo, Micro, Robot or LilyPadUSB.')
parser.add_argument('--verbose', action='store_true', help="Watch what's going on on STDERR.")
parser.add_argument('--period', default=0.1, help='Specify the DTR pulse width in seconds.')
parser.add_argument('port', nargs=1, help='Serial device e.g. /dev/ttyACM0')
args = parser.parse_args()
-if args.caterina:
+
+def list_ports(output=False):
+ """ Lists serial ports attached
+
+ :returns
+ A list of paths to serial ports on system
+ """
+ ports = serial.tools.list_ports.comports()
+ connected = [port[0] for port in ports]
+ if output:
+ print(connected)
+
+ return connected
+
+
+def new_port(old, new):
+ """ Checks if a new port has attached
+
+ Args:
+ old: previous list of ports to check
+ new: current list of ports to check
+ Returns:
+ index of port in 'new' if new port found, otherwise -1
+ """
+ new_port = -1
+
+ for port in new:
+ if port not in old:
+ new_port = new.index(port)
+ break
+
+ return new_port
+
+
+if args.zero:
+ # number of trys to attempt
+ zero_attempts = 20 # ~2 seconds
+ initial_ports = list_ports(args.verbose)
+
+ if args.verbose:
+ print('Attempting to enter bootloader using 1200 bps open/close on port %s' % args.port[0])
+
+ ser = serial.Serial(args.port[0], 57600)
+ ser.close()
+
+ if pyserial_version < 3:
+ ser.setBaudrate(1200)
+ else:
+ ser.baudrate = 1200
+
+ # do the open/close at 1200 BAUD
+ ser.open()
+ ser.close()
+
+ if args.verbose:
+ print('Done. Waiting for bootloader port to attach...')
+
+ # get new list of ports
+ reset_ports = list_ports(args.verbose)
+
+ # wait for new port or port to return
+ port_index = new_port(initial_ports, reset_ports)
+
+ # keep checking until new port appears or timeout
+ while port_index < 0:
+ # count down attempts and leave if expired
+ zero_attempts -= 1
+ if zero_attempts < 0:
+ break
+ sleep(0.1)
+ # get list of ports after bootloader toggle performed
+ reset_ports = list_ports(args.verbose)
+ # if a port drops, set initial ports to reset ports so that
+ # next attached device will be new port
+ if (len(reset_ports) < len(initial_ports)):
+ initial_ports = reset_ports
+ # check if a new port has attached and return the index if it has
+ port_index = new_port(initial_ports, reset_ports)
+ # return the new port if detected, otherwise return passed port
+ if port_index is -1:
+ bootloader_port = args.port[0]
+ else:
+ bootloader_port = reset_ports[port_index]
+
+ # print so that `tail -1` can be piped for bootloader port
+ print(bootloader_port)
+elif args.caterina:
if args.verbose: print('Forcing reset using 1200bps open/close on port %s' % args.port[0])
ser = serial.Serial(args.port[0], 57600)
ser.close()