diff --git a/ltchiptool/soc/ambz2/util/ambz2tool.py b/ltchiptool/soc/ambz2/util/ambz2tool.py index 2c91bc5..1e7e9c9 100644 --- a/ltchiptool/soc/ambz2/util/ambz2tool.py +++ b/ltchiptool/soc/ambz2/util/ambz2tool.py @@ -83,16 +83,20 @@ def command(self, cmd: str) -> None: def read(self, count: int = None) -> bytes: response = b"" end = time() + self.read_timeout + self.s.timeout = self.read_timeout while time() < end: + to_read = self.s.in_waiting + if not to_read: + continue if count: - read = self.s.read(count - len(response)) - else: - read = self.s.read_all() + to_read = min(to_read, count - len(response)) + read = self.s.read(to_read) + if not read: + continue + end = time() + self.read_timeout response += read if count and len(response) >= count: break - if read: - end = time() + self.read_timeout if not response: raise TimeoutError(f"Timeout in read({count}) - no data received") @@ -139,11 +143,9 @@ def pop_timeout(self) -> None: def error_flush(self) -> None: # try to clean up the serial buffer - # no data for 0.8 s means that the chip stopped sending bytes - self.push_timeout(0.8) - while True: - if not self.s.read(128): - break + # no data for 0.5 s means that the chip stopped sending bytes + self.push_timeout(0.5) + self.read() # read all available data self.pop_timeout() # pop timeout of the failing function self.pop_timeout() @@ -178,7 +180,9 @@ def change_baudrate(self, baudrate: int) -> None: self.command(f"ucfg {baudrate} 0 0") # change Serial port baudrate stream("-- UART: Changing port baudrate") + self.s.close() self.s.baudrate = baudrate + self.s.open() # wait up to 1 second for OK response self.push_timeout(1.0) try: @@ -197,7 +201,10 @@ def dump_words(self, start: int, count: int) -> Generator[List[int], None, None] self.push_timeout(max(min(count, 256), 16) * 1.5 / 500.0) # one line is 57 chars long, and it holds 4 words # make it 32 KiB at most - self.s.set_buffer_size(rx_size=min(32768, 57 * (count // 4))) + try: + self.s.set_buffer_size(rx_size=min(32768, 57 * (count // 4))) + except AttributeError: + pass read_count = 0 self.flush() @@ -227,7 +234,10 @@ def dump_bytes(self, start: int, count: int) -> Generator[bytes, None, None]: self.push_timeout(max(min(count, 1024), 64) * 0.5 / 500.0) # one line is 78 chars long, and it holds 16 bytes # make it 32 KiB at most - self.s.set_buffer_size(rx_size=min(32768, 78 * (count // 16))) + try: + self.s.set_buffer_size(rx_size=min(32768, 78 * (count // 16))) + except AttributeError: + pass read_count = 0 self.flush() @@ -403,6 +413,10 @@ def memory_read( # can only check SHA of flash hash_check = False + # determine a reliable maximum chunk size + baud_coef = int(1 / self.s.baudrate**0.5 * 2000) + chunk_size = min(2**baud_coef * 1024, chunk_size) + chunk = b"" sha = sha256() sha_size = 0