From 0016d4ea25d95614417f1334c58fd9571052a809 Mon Sep 17 00:00:00 2001 From: slederer Date: Fri, 5 Dec 2025 00:58:15 +0100 Subject: [PATCH] utils/serload: add interactive mode xfer: reset block count on transfer start --- progs/xfer.pas | 1 + utils/serload.py | 151 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 42 deletions(-) diff --git a/progs/xfer.pas b/progs/xfer.pas index 13a7cc2..0d871d2 100644 --- a/progs/xfer.pas +++ b/progs/xfer.pas @@ -226,6 +226,7 @@ begin if not invalid then begin open(xferFile, filename, ModeOverwrite); + blockNo := 0; done := false; repeat serReadBlock(ok); diff --git a/utils/serload.py b/utils/serload.py index 6ccc4a6..e69837f 100644 --- a/utils/serload.py +++ b/utils/serload.py @@ -16,6 +16,7 @@ # limitations under the License. import sys +import os import serial import time import random @@ -41,30 +42,6 @@ def get_default_device(): return '/dev/ttyUSB1' -def serwrite_slow(databytes, ser): - total = len(data) - count = 1 - for d in data: - sys.stdout.write("writing {0:02x} {1:04d}/{2:04d}\r".format(ord(d), count, total)) - ser.write(bytes(d,"utf8")) - count += 1 - time.sleep(0.020) - print() - - -def serwrite(datafile, ser): - with open(datafile) as f: - data = f.read() - total = len(data) - count = 1 - for d in data: - sys.stdout.write("writing {0:02x} {1:04d}/{2:04d}\r".format(ord(d), count, total)) - ser.write(bytes(d,"utf8")) - count += 1 - time.sleep(0.020) - print() - - def checksum(databytes): i = 0 cksum = 0 @@ -85,10 +62,26 @@ def sendchar(char, ser): ser.write(char.to_bytes(1, 'big')) -def sendcommand(ser, cmd=b'L'): +def sendcommand(ser, cmd=b'L', verbose=False): + verbose = True ser.write(cmd) resp = ser.read_until() - print(cmd,"sent, response:", str(resp)) + if verbose: + print(cmd,"sent, response:", str(resp)) + return resp + + +# send command and wait for echo +def commandwait(ser, cmd): + resp = sendcommand(ser, cmd, verbose=False) + if len(resp) == 0: + print("timeout sending '{}' command".format(cmd)) + return None + + if resp != bytearray(cmd + b"\r\n"): + print("invalid response to '{}' command".format(cmd)) + return None + return resp @@ -153,6 +146,8 @@ def serload_bin(datafile, ser): data += bytearray(pad) + print("{} total blocks".format((len(data) + blocksize - 1) // blocksize)) + if not send_size_header(ser, filesize): print("Error sending size header.") return @@ -279,18 +274,8 @@ def serdownload(fname, ser): def mput(filenames, ser): for f in filenames: - f_encoded = f.encode('utf8') - print("Setting filename", f) - resp = sendcommand(ser, b'S') - if len(resp) == 0: - print("timeout sending 'S' command") - return - if resp != b'S\r\n' and resp != b'> S\r\n': - print("unrecognized response to 'S' command, aborting") - return - resp = sendcommand(ser, f_encoded + b'\r') - if not f_encoded in resp: - print("unrecognized response to filename, aborting") + resp = set_filename(f, ser) + if resp is None: return serload_bin(f, ser) @@ -299,12 +284,92 @@ def mput(filenames, ser): time.sleep(2) +def set_filename(f, ser): + f_encoded = f.encode('utf8') + print("Setting filename", f) + resp = commandwait(ser, b'S') + if resp is None: + return None + resp = sendcommand(ser, f_encoded + b'\r') + if not f_encoded in resp: + print("unrecognized response to filename, aborting") + return None + return resp + + +def getnamedfile(filename, ser): + resp = set_filename(filename, ser) + if resp is None: + return None + serdownload(filename, ser) + + +def putnamedfile(filename, ser): + resp = set_filename(filename, ser) + if resp is None: + return None + serload_bin(filename, ser) + print("Remote status:") + showdata(ser) + + +def showdata(ser): + + promptseen = False + + while not promptseen: + c = ser.read(1) + if c == b'>': + promptseen = True + else: + print(c.decode('utf8'), end='') + rest = ser.read(1) + + +def localdir(): + result = os.walk(".") + for dirpath, dirnames, filenames in os.walk("."): + for f in filenames: + print(f) + break + + +def interactive(ser): + done = False + while not done: + args = input("> ").strip().split() + if len(args) > 0: + cmd = args[0] + args.pop(0) + if cmd == 'dir': + if commandwait(ser, b'Y') is None: + return + showdata(ser) + elif cmd == 'get': + if len(args) > 1: + print("exactly one argument required (filename)") + else: + getnamedfile(args[0], ser) + elif cmd == 'put': + if len(args) > 1: + print("exactly one argument required (filename)") + else: + putnamedfile(args[0], ser) + elif cmd == 'ldir': + if len(args) > 0: + print("superfluous argument") + else: + localdir() + else: + print("Unknown command. Valid commands are: dir get ldir put") + + if __name__ == "__main__": argparser = argparse.ArgumentParser( description='transfer files from/to the Tridora-CPU') argparser.add_argument('-d', '--device', help='serial device', default=get_default_device()) - argparser.add_argument('command', choices=['get', 'put', 'mput']) - argparser.add_argument('filename', nargs='+') + argparser.add_argument('command', choices=['get', 'put', 'mput', 'interactive']) + argparser.add_argument('filename', nargs='*') args = argparser.parse_args() cmd = args.command @@ -319,8 +384,10 @@ if __name__ == "__main__": serload_bin(filenames[0], ser) elif cmd == 'mput': mput(filenames, ser) + elif cmd == 'interactive': + interactive(ser) else: print("should not get here") - if cmd is not None: - ser.close() + #if cmd is not None: + # ser.close()