aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/flash_usb.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/flash_usb.py')
-rwxr-xr-xscripts/flash_usb.py143
1 files changed, 91 insertions, 52 deletions
diff --git a/scripts/flash_usb.py b/scripts/flash_usb.py
index e290f7f3..99e291fc 100755
--- a/scripts/flash_usb.py
+++ b/scripts/flash_usb.py
@@ -6,35 +6,39 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, re, subprocess, optparse, time, fcntl, termios, struct
+
class error(Exception):
pass
+
# Attempt to enter bootloader via 1200 baud request
def enter_bootloader(device):
try:
- f = open(device, 'rb')
+ f = open(device, "rb")
fd = f.fileno()
- fcntl.ioctl(fd, termios.TIOCMBIS, struct.pack('I', termios.TIOCM_DTR))
+ fcntl.ioctl(fd, termios.TIOCMBIS, struct.pack("I", termios.TIOCM_DTR))
t = termios.tcgetattr(fd)
t[4] = t[5] = termios.B1200
sys.stderr.write("Entering bootloader on %s\n" % (device,))
termios.tcsetattr(fd, termios.TCSANOW, t)
- fcntl.ioctl(fd, termios.TIOCMBIC, struct.pack('I', termios.TIOCM_DTR))
+ fcntl.ioctl(fd, termios.TIOCMBIC, struct.pack("I", termios.TIOCM_DTR))
f.close()
except (IOError, OSError) as e:
pass
+
# Translate a serial device name to a stable serial name in /dev/serial/by-path/
def translate_serial_to_tty(device):
ttyname = os.path.realpath(device)
- if not os.path.exists('/dev/serial/by-path/'):
+ if not os.path.exists("/dev/serial/by-path/"):
raise error("Unable to find serial 'by-path' folder")
- for fname in os.listdir('/dev/serial/by-path/'):
- fname = '/dev/serial/by-path/' + fname
+ for fname in os.listdir("/dev/serial/by-path/"):
+ fname = "/dev/serial/by-path/" + fname
if os.path.realpath(fname) == ttyname:
return ttyname, fname
return ttyname, ttyname
+
# Translate a serial device name to a usb path (suitable for dfu-util)
def translate_serial_to_usb_path(device):
realdev = os.path.realpath(device)
@@ -50,9 +54,10 @@ def translate_serial_to_usb_path(device):
devpath = os.path.realpath("/sys/class/tty/%s/device" % (fname,))
return m.group("path"), devpath
+
# Wait for a given path to appear
def wait_path(path, alt_path=None):
- time.sleep(.100)
+ time.sleep(0.100)
start_alt_path = None
end_time = time.time() + 4.0
while 1:
@@ -67,13 +72,14 @@ def wait_path(path, alt_path=None):
start_alt_path = cur_time
continue
if cur_time >= start_alt_path + 0.300:
- sys.stderr.write("Device reconnect on alt path %s\n" % (
- alt_path,))
+ sys.stderr.write("Device reconnect on alt path %s\n" % (alt_path,))
return alt_path
if cur_time > end_time:
return path
-CANBOOT_ID ="1d50:6177"
+
+CANBOOT_ID = "1d50:6177"
+
def detect_canboot(devpath):
usbdir = os.path.dirname(devpath)
@@ -87,6 +93,7 @@ def detect_canboot(devpath):
usbid = "%s:%s" % (vid, pid)
return usbid == CANBOOT_ID
+
def call_flashcan(device, binfile):
try:
import serial
@@ -97,18 +104,19 @@ def call_flashcan(device, binfile):
" %s -m pip install pyserial\n\n" % (sys.executable,)
)
sys.exit(-1)
- args = [sys.executable, "lib/canboot/flash_can.py", "-d",
- device, "-f", binfile]
- sys.stderr.write(" ".join(args) + '\n\n')
+ args = [sys.executable, "lib/canboot/flash_can.py", "-d", device, "-f", binfile]
+ sys.stderr.write(" ".join(args) + "\n\n")
res = subprocess.call(args)
if res != 0:
sys.stderr.write("Error running flash_can.py\n")
sys.exit(-1)
+
def flash_canboot(options, binfile):
ttyname, pathname = translate_serial_to_tty(options.device)
call_flashcan(pathname, binfile)
+
# Flash via a call to bossac
def flash_bossac(device, binfile, extra_flags=[]):
ttyname, pathname = translate_serial_to_tty(device)
@@ -116,7 +124,7 @@ def flash_bossac(device, binfile, extra_flags=[]):
pathname = wait_path(pathname, ttyname)
baseargs = ["lib/bossac/bin/bossac", "-U", "-p", pathname]
args = baseargs + extra_flags + ["-w", binfile, "-v"]
- sys.stderr.write(" ".join(args) + '\n\n')
+ sys.stderr.write(" ".join(args) + "\n\n")
res = subprocess.call(args)
if res != 0:
raise error("Error running bossac")
@@ -130,21 +138,23 @@ def flash_bossac(device, binfile, extra_flags=[]):
except subprocess.CalledProcessError as e:
pass
+
# Invoke the dfu-util program
def call_dfuutil(flags, binfile, sudo):
args = ["dfu-util"] + flags + ["-D", binfile]
if sudo:
args.insert(0, "sudo")
- sys.stderr.write(" ".join(args) + '\n\n')
+ sys.stderr.write(" ".join(args) + "\n\n")
res = subprocess.call(args)
if res != 0:
raise error("Error running dfu-util")
+
# Flash via a call to dfu-util
def flash_dfuutil(device, binfile, extra_flags=[], sudo=True):
hexfmt_r = re.compile(r"^[a-fA-F0-9]{4}:[a-fA-F0-9]{4}$")
if hexfmt_r.match(device.strip()):
- call_dfuutil(["-d", ","+device.strip()] + extra_flags, binfile, sudo)
+ call_dfuutil(["-d", "," + device.strip()] + extra_flags, binfile, sudo)
return
ttyname, serbypath = translate_serial_to_tty(device)
buspath, devpath = translate_serial_to_usb_path(device)
@@ -155,15 +165,17 @@ def flash_dfuutil(device, binfile, extra_flags=[], sudo=True):
else:
call_dfuutil(["-p", buspath] + extra_flags, binfile, sudo)
+
def call_hidflash(binfile, sudo):
args = ["lib/hidflash/hid-flash", binfile]
if sudo:
args.insert(0, "sudo")
- sys.stderr.write(" ".join(args) + '\n\n')
+ sys.stderr.write(" ".join(args) + "\n\n")
res = subprocess.call(args)
if res != 0:
raise error("Error running hid-flash")
+
# Flash via call to hid-flash
def flash_hidflash(device, binfile, sudo=True):
hexfmt_r = re.compile(r"^[a-fA-F0-9]{4}:[a-fA-F0-9]{4}$")
@@ -179,6 +191,7 @@ def flash_hidflash(device, binfile, sudo=True):
else:
call_hidflash(binfile, sudo)
+
# Call Klipper modified "picoboot"
def call_picoboot(bus, addr, binfile, sudo):
args = ["lib/rp2040_flash/rp2040_flash", binfile]
@@ -186,11 +199,12 @@ def call_picoboot(bus, addr, binfile, sudo):
args.extend([bus, addr])
if sudo:
args.insert(0, "sudo")
- sys.stderr.write(" ".join(args) + '\n\n')
+ sys.stderr.write(" ".join(args) + "\n\n")
res = subprocess.call(args)
if res != 0:
raise error("Error running rp2040_flash")
+
# Flash via Klipper modified "picoboot"
def flash_picoboot(device, binfile, sudo):
ttyname, serbypath = translate_serial_to_tty(device)
@@ -213,31 +227,32 @@ def flash_picoboot(device, binfile, sudo):
# Device specific helpers
######################################################################
+
def flash_atsam3(options, binfile):
try:
flash_bossac(options.device, binfile, ["-e", "-b"])
except error as e:
- sys.stderr.write("Failed to flash to %s: %s\n" % (
- options.device, str(e)))
+ sys.stderr.write("Failed to flash to %s: %s\n" % (options.device, str(e)))
sys.exit(-1)
+
def flash_atsam4(options, binfile):
try:
flash_bossac(options.device, binfile, ["-e"])
except error as e:
- sys.stderr.write("Failed to flash to %s: %s\n" % (
- options.device, str(e)))
+ sys.stderr.write("Failed to flash to %s: %s\n" % (options.device, str(e)))
sys.exit(-1)
+
def flash_atsamd(options, binfile):
extra_flags = ["--offset=0x%x" % (options.start,), "-b", "-R"]
try:
flash_bossac(options.device, binfile, extra_flags)
except error as e:
- sys.stderr.write("Failed to flash to %s: %s\n" % (
- options.device, str(e)))
+ sys.stderr.write("Failed to flash to %s: %s\n" % (options.device, str(e)))
sys.exit(-1)
+
SMOOTHIE_HELP = """
Failed to flash to %s: %s
@@ -256,6 +271,7 @@ and then restart the Smoothieboard with that SD card.
"""
+
def flash_lpc176x(options, binfile):
try:
flash_dfuutil(options.device, binfile, [], options.sudo)
@@ -263,6 +279,7 @@ def flash_lpc176x(options, binfile):
sys.stderr.write(SMOOTHIE_HELP % (options.device, str(e)))
sys.exit(-1)
+
STM32F1_HELP = """
Failed to flash to %s: %s
@@ -277,18 +294,18 @@ If attempting to flash via 3.3V serial, then use:
"""
+
def flash_stm32f1(options, binfile):
try:
if options.start == 0x8000800:
flash_hidflash(options.device, binfile, options.sudo)
else:
- flash_dfuutil(options.device, binfile, ["-R", "-a", "2"],
- options.sudo)
+ flash_dfuutil(options.device, binfile, ["-R", "-a", "2"], options.sudo)
except error as e:
- sys.stderr.write(STM32F1_HELP % (
- options.device, str(e), options.device))
+ sys.stderr.write(STM32F1_HELP % (options.device, str(e), options.device))
sys.exit(-1)
+
STM32F4_HELP = """
Failed to flash to %s: %s
@@ -303,19 +320,21 @@ If attempting to flash via 3.3V serial, then use:
"""
+
def flash_stm32f4(options, binfile):
start = "0x%x:leave" % (options.start,)
try:
if options.start == 0x8004000:
flash_hidflash(options.device, binfile, options.sudo)
else:
- flash_dfuutil(options.device, binfile,
- ["-R", "-a", "0", "-s", start], options.sudo)
+ flash_dfuutil(
+ options.device, binfile, ["-R", "-a", "0", "-s", start], options.sudo
+ )
except error as e:
- sys.stderr.write(STM32F4_HELP % (
- options.device, str(e), options.device))
+ sys.stderr.write(STM32F4_HELP % (options.device, str(e), options.device))
sys.exit(-1)
+
RP2040_HELP = """
Failed to flash to %s: %s
@@ -329,9 +348,10 @@ device as a usb drive, and copy klipper.uf2 to the device.
"""
+
def flash_rp2040(options, binfile):
rawdev = "2e8a:0003"
- if options.mcutype == 'rp2350':
+ if options.mcutype == "rp2350":
rawdev = "2e8a:000f"
try:
if options.device.lower() == rawdev:
@@ -342,15 +362,25 @@ def flash_rp2040(options, binfile):
sys.stderr.write(RP2040_HELP % (options.device, str(e), rawdev))
sys.exit(-1)
+
MCUTYPES = {
- 'sam3': flash_atsam3, 'sam4': flash_atsam4, 'same70': flash_atsam4,
- 'samd': flash_atsamd, 'same5': flash_atsamd,
- 'lpc176': flash_lpc176x, 'stm32f103': flash_stm32f1,
- 'stm32f4': flash_stm32f4, 'stm32f042': flash_stm32f4,
- 'stm32f070': flash_stm32f4, 'stm32f072': flash_stm32f4,
- 'stm32g0b1': flash_stm32f4, 'stm32f7': flash_stm32f4,
- 'stm32h7': flash_stm32f4, 'stm32l4': flash_stm32f4,
- 'stm32g4': flash_stm32f4, 'rp2': flash_rp2040,
+ "sam3": flash_atsam3,
+ "sam4": flash_atsam4,
+ "same70": flash_atsam4,
+ "samd": flash_atsamd,
+ "same5": flash_atsamd,
+ "lpc176": flash_lpc176x,
+ "stm32f103": flash_stm32f1,
+ "stm32f4": flash_stm32f4,
+ "stm32f042": flash_stm32f4,
+ "stm32f070": flash_stm32f4,
+ "stm32f072": flash_stm32f4,
+ "stm32g0b1": flash_stm32f4,
+ "stm32f7": flash_stm32f4,
+ "stm32h7": flash_stm32f4,
+ "stm32l4": flash_stm32f4,
+ "stm32g4": flash_stm32f4,
+ "rp2": flash_rp2040,
}
@@ -358,17 +388,26 @@ MCUTYPES = {
# Startup
######################################################################
+
def main():
usage = "%prog [options] -t <type> -d <device> <klipper.bin>"
opts = optparse.OptionParser(usage)
- opts.add_option("-t", "--type", type="string", dest="mcutype",
- help="micro-controller type")
- opts.add_option("-d", "--device", type="string", dest="device",
- help="serial port device")
- opts.add_option("-s", "--start", type="int", dest="start",
- help="start address in flash")
- opts.add_option("--no-sudo", action="store_false", dest="sudo",
- default=True, help="do not run sudo")
+ opts.add_option(
+ "-t", "--type", type="string", dest="mcutype", help="micro-controller type"
+ )
+ opts.add_option(
+ "-d", "--device", type="string", dest="device", help="serial port device"
+ )
+ opts.add_option(
+ "-s", "--start", type="int", dest="start", help="start address in flash"
+ )
+ opts.add_option(
+ "--no-sudo",
+ action="store_false",
+ dest="sudo",
+ default=True,
+ help="do not run sudo",
+ )
options, args = opts.parse_args()
if len(args) != 1:
opts.error("Incorrect number of arguments")
@@ -379,12 +418,12 @@ def main():
flash_func = func
break
if flash_func is None:
- opts.error("USB flashing is not supported for MCU '%s'"
- % (options.mcutype,))
+ opts.error("USB flashing is not supported for MCU '%s'" % (options.mcutype,))
if not options.device:
sys.stderr.write("\nPlease specify FLASH_DEVICE\n\n")
sys.exit(-1)
flash_func(options, args[0])
-if __name__ == '__main__':
+
+if __name__ == "__main__":
main()