import serial
import struct
import sys
import time

offset = 0x800
tty = 'tty'
baud = 115200
chunksize = 128


def write(s, offset, dat):
    for i in range(0, len(dat), chunksize):
        chunk = dat[i: i + chunksize]
        cmd = struct.pack('<cII', b'c', offset + i, len(chunk))

        print(f'Sending {len(chunk)} bytes @0x{offset + i:04x}')

        s.write(cmd)
        s.write(chunk)

        ack = s.read(2)
        if len(ack) < 2:
            raise RuntimeError(f'timeout waiting for full ack. got {ack}')
        if ack[0] != b'a'[0]:
            raise RuntimeError(f'expected ack, got this instead: {ack}')
        print(f'Ack! len={ack[1]}')


def jump(s, offset):
        cmd = struct.pack('<cI', b'j', offset)
        s.write(cmd)


def main():
    binfile = sys.argv[1]
    with open(binfile, 'rb') as f:
        dat = f.read()

    s = serial.Serial(tty, baud, timeout=1)
    write(s, offset, dat)
    jump(s, offset)
    last_dat = time.time()

    while True:
        dat = s.read()
        if not dat:
            if time.time() - last_dat > 1.0:
                print('Data timeout')
                break
            continue
        last_dat = time.time()
        sys.stdout.buffer.write(dat)


if __name__ == "__main__":
    main()
