tools: Add flash.py
This commit is contained in:
parent
e1672bb712
commit
07bac62438
115
tools/flash.py
Executable file
115
tools/flash.py
Executable file
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# -------------------------------------------------------------------------- --
|
||||
# TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||||
# -------------------------------------------------------------------------- --
|
||||
# Interface program for the bootrom. Basically a serial-to-wishbone bridge.
|
||||
# -------------------------------------------------------------------------- --
|
||||
# Author : Markus Koch <markus@notsyncing.net>
|
||||
# Contributors : None
|
||||
# License : Mozilla Public License (MPL) Version 2
|
||||
# -------------------------------------------------------------------------- --
|
||||
|
||||
import serial
|
||||
import sys
|
||||
from ast import literal_eval
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
ser = serial.Serial('/dev/ttyUSB0', 19200, timeout=2)
|
||||
|
||||
def sread(address, length, quiet = False):
|
||||
if not quiet:
|
||||
eprint(f'Reading {length} bytes from 0x{address:08x}...')
|
||||
ser.write(b'\x02' + address.to_bytes(4, byteorder='big') + length.to_bytes(4, byteorder='big'))
|
||||
data = bytes()
|
||||
while length > 0:
|
||||
maxpkg = min(length, 128)
|
||||
rd = ser.read(maxpkg)
|
||||
if len(rd) == 0:
|
||||
eprint("ERROR: Receive timeout")
|
||||
return None
|
||||
data += rd
|
||||
length -= len(rd)
|
||||
return data
|
||||
|
||||
def swrite(address, data, quiet = False):
|
||||
if not quiet:
|
||||
eprint('Writing {} bytes to 0x{:08x}...'.format(len(data), address))
|
||||
ser.write(b'\x01' + address.to_bytes(4, byteorder='big') + len(data).to_bytes(4, byteorder='big') + data)
|
||||
return 0
|
||||
|
||||
def sjump(address, quiet = False):
|
||||
if not quiet:
|
||||
eprint(f'Jumping to 0x{address:08x}...')
|
||||
ser.write(b'\x03' + address.to_bytes(4, byteorder='big'))
|
||||
return 0
|
||||
|
||||
def get_diff(a, b):
|
||||
diff = 0
|
||||
for i in range(0, len(a)):
|
||||
if a[i] != b[i]:
|
||||
print('[0x{:08x}] 0x{:02x} => 0x{:02x}'.format(i, a[i], b[i]))
|
||||
diff += 1
|
||||
return diff
|
||||
|
||||
def probe():
|
||||
r = sread(0, 4, quiet = True);
|
||||
if r != b'7\x03\x00\x81':
|
||||
eprint("ERROR: Probe failed! Check that the device is in bootloader mode.")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def program(filename, addr=0, check=True):
|
||||
f = open(filename, "rb")
|
||||
d = bytes(f.read())
|
||||
swrite(addr, d)
|
||||
if check:
|
||||
r = sread(addr, len(d))
|
||||
if r is None:
|
||||
eprint("Programming failed")
|
||||
return 1
|
||||
diff_cnt = get_diff(d, r)
|
||||
if diff_cnt == 0:
|
||||
eprint("Programming OK.")
|
||||
return 0
|
||||
else:
|
||||
print(f"Programming failed, {diff_cnt} bytes differ.")
|
||||
return 2
|
||||
else:
|
||||
return 0
|
||||
|
||||
def monitor():
|
||||
print("Monitoring serial, press Ctrl+C to stop.")
|
||||
while 1:
|
||||
rd = ser.read(1)
|
||||
if len(rd) > 0:
|
||||
sys.stdout.buffer.write(bytes(rd))
|
||||
sys.stdout.buffer.flush()
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
eprint("usage: " + sys.argv[0] + " [write|dump|jump] [address] [file]")
|
||||
exit()
|
||||
|
||||
command = sys.argv[1]
|
||||
addr = literal_eval(sys.argv[2])
|
||||
|
||||
if probe():
|
||||
exit(-1)
|
||||
|
||||
ret = 0
|
||||
if command == "write":
|
||||
file = sys.argv[3]
|
||||
ret = program(file, addr)
|
||||
elif command == "dump":
|
||||
length = literal_eval(sys.argv[3])
|
||||
sys.stdout.buffer.write(sread(addr, length))
|
||||
elif command == "jump":
|
||||
ret = sjump(addr)
|
||||
monitor()
|
||||
else:
|
||||
ret = -2
|
||||
eprint("Unknown command")
|
||||
|
||||
exit(ret)
|
Loading…
Reference in New Issue
Block a user