diff --git a/src/picowatch.py b/src/picowatch.py index cc2ee06..2f834ff 100644 --- a/src/picowatch.py +++ b/src/picowatch.py @@ -191,6 +191,7 @@ class Telnet: class Pyboard(object): i: int = 0 + boot_status: bool = False serial: Union[Serial, Telnet] def __init__(self, device: str, baudrate: int = 115200, login: str = 'micro', password: str = 'python'): @@ -231,6 +232,7 @@ class Pyboard(object): self.serial.write(b'\x02') def send_ctrl_c(self) -> bytes: + self.boot_status = False # Ctrl-C cancels any input, or interrupts the currently running code. for _ in range(0, 2): self.serial.write(b'\x03') @@ -251,14 +253,14 @@ class Pyboard(object): def read_until(self, delimiter: bytes, stream_output: bool = False, show_status: bool = False) -> Optional[bytes]: data = b'' - timeout = 0 + timeout = 300 max_len = len(delimiter) - - while not timeout >= 1000: + + while timeout > 0: if data.endswith(delimiter): return data elif self.serial.inWaiting() > 0: - timeout = 0 + timeout = 300 data += self.serial.read(1) if stream_output: @@ -268,8 +270,8 @@ class Pyboard(object): elif show_status: self.transfer_status() else: - timeout += 1 - time.sleep(0.0001) + timeout -= 1 + time.sleep(0.01) def boot(self): data = b'' @@ -280,13 +282,21 @@ class Pyboard(object): if not self.read_until(self.send_ctrl_d()): raise Exception('REPL: could not soft reboot') - while not data.endswith(b'\r\nMicroPython v') and not data.endswith(b'.\r\n>>>'): - if self.serial.inWaiting(): - data = data[-15:] + self.serial.read(1) - sys.stdout.buffer.write(data[-1:]) - sys.stdout.buffer.flush() + output_status = True + self.boot_status = True - sys.stdout.buffer.write(b'\r' + b' ' * 20 + b'\r') + while self.boot_status and output_status: + if self.serial.inWaiting(): + sys.stdout.buffer.write((data := data[-15:] + self.serial.read(1))[-1:]) + sys.stdout.buffer.flush() + output_status = not data.endswith(b'\r\nMicroPython v') and not data.endswith(b'.\r\n>>>') + + if not output_status: + sys.stdout.buffer.write(b'\r<<< Program terminated\r\n') + elif not self.boot_status: + sys.stdout.buffer.write(b'\r<<< Program terminated with Exception\r\n') + + self.boot_status = False def __enter__(self): self.send_ctrl_c() @@ -340,9 +350,9 @@ class Pyboard(object): for call in traceback[1][:-2].split('\\r\\n'): reason += f'{call}\n' - raise Exception('' + reason.strip()) + raise Exception('\r' + reason.strip()) else: - raise Exception(exception) + raise Exception('\r' + exception) return data.strip()