From 04ab5f335fb6461299f18f093f8075f6ceca3533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Mon, 30 Oct 2023 15:37:12 +0100 Subject: [PATCH] [gui] Automatically calculate write length, check write offsets --- ltchiptool/gui/ltchiptool.wxui | 7 ++--- ltchiptool/gui/ltchiptool.xrc | 7 ++--- ltchiptool/gui/panels/flash.py | 52 +++++++++++++++++++--------------- ltchiptool/gui/work/flash.py | 12 ++++---- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/ltchiptool/gui/ltchiptool.wxui b/ltchiptool/gui/ltchiptool.wxui index a56643a..df9569e 100644 --- a/ltchiptool/gui/ltchiptool.wxui +++ b/ltchiptool/gui/ltchiptool.wxui @@ -329,7 +329,6 @@ class="wxComboBox" style="wxCB_READONLY" var_name="combo_family" - disabled="1" borders="wxBOTTOM|wxRIGHT|wxLEFT" colspan="3" flags="wxEXPAND" @@ -374,16 +373,16 @@ row="2" /> 5 - 0 @@ -426,21 +425,21 @@ wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND 5 - 0 + 0x0 wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND 5 - 0 + 0x0 wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND 5 - 0 + All data diff --git a/ltchiptool/gui/panels/flash.py b/ltchiptool/gui/panels/flash.py index d2d4690..4d2ce53 100644 --- a/ltchiptool/gui/panels/flash.py +++ b/ltchiptool/gui/panels/flash.py @@ -112,7 +112,7 @@ def SetSettings( file: str = None, offset: int = None, skip: int = None, - length: int = None, + length: int | None = None, prev_file: str = None, auto_file: str = None, **_, @@ -190,7 +190,7 @@ def OnUpdate(self, target: wx.Window = None): if not need_offset: self.offset = self.detection.offset self.skip = self.detection.skip - self.length = self.detection.length + self.length = None if is_uf2 else self.detection.length match self.detection.type: case Detection.Type.UNRECOGNIZED if auto: @@ -211,6 +211,20 @@ def OnUpdate(self, target: wx.Window = None): if manual: warnings.append("Warning: using custom options") + if self.skip >= self.detection.length: + errors.append( + f"Skip offset (0x{self.skip:X}) " + f"not within input file bounds " + f"(0x{self.detection.length:X})" + ) + elif self.skip + (self.length or 0) > self.detection.length: + errors.append( + f"Writing length (0x{self.skip:X} + 0x{self.length:X}) " + f"not within input file bounds " + f"(0x{self.detection.length:X})" + ) + errors.append("") + else: self.FileText.SetLabel("Output file") self.LengthText.SetLabel("Reading length") @@ -225,20 +239,15 @@ def OnUpdate(self, target: wx.Window = None): warnings.append("Using manual parameters") verbose( - f"Update: read_full={self.read_full}, " + f"Update: " f"target={type(target).__name__}, " f"port={self.port}, " f"family={self.family}", ) - if self.prev_read_full is not self.read_full: - # switching "entire chip" reading - update input text - self.length = self.length or 0x200000 - self.prev_read_full = self.read_full - if not self.family: errors.append("Choose the chip family") - if not self.length and not self.read_full: + if self.length == 0: errors.append("Enter a correct length") if not self.port: errors.append("Choose a serial port") @@ -369,44 +378,41 @@ def file(self, value: str | None): self.DoUpdate(self.File) @property - def offset(self): + def offset(self) -> int: text: str = self.Offset.GetValue().strip() or "0" value = int_or_zero(text) return value @offset.setter - def offset(self, value: int): + def offset(self, value: int) -> None: value = value or 0 self.Offset.SetValue(f"0x{value:X}") @property - def skip(self): + def skip(self) -> int: text: str = self.Skip.GetValue().strip() or "0" value = int_or_zero(text) return value @skip.setter - def skip(self, value: int): + def skip(self, value: int) -> None: value = value or 0 self.Skip.SetValue(f"0x{value:X}") @property - def length(self): - text: str = self.Length.GetValue().strip() or "0" + def length(self) -> int | None: + text: str = self.Length.GetValue().strip() + if not text: + return None value = int_or_zero(text) return value @length.setter def length(self, value: int | None): - value = value or 0 - if self.read_full: - self.Length.SetValue("Entire chip") - else: + if value: self.Length.SetValue(f"0x{value:X}") - - @property - def read_full(self): - return self.length == 0 and self.auto_detect and self.operation != FlashOp.WRITE + else: + self.Length.SetValue("") def make_dump_filename(self): if not self.file: diff --git a/ltchiptool/gui/work/flash.py b/ltchiptool/gui/work/flash.py index a766959..5b28f2b 100644 --- a/ltchiptool/gui/work/flash.py +++ b/ltchiptool/gui/work/flash.py @@ -62,9 +62,8 @@ def run_impl(self): def stop(self): super().stop() - if self.ctx: - # try to break UF2 flashing - self.soc.flash_disconnect() + # try to break flashing & cleanup + self.soc.flash_disconnect() def _link(self): self.soc.flash_set_connection(FlashConnection(self.port, self.baudrate)) @@ -114,7 +113,7 @@ def _do_write(self): return file = open(self.file, "rb") - size = stat(self.file).st_size + file_size = stat(self.file).st_size _read = file.read def read(n: int = -1) -> bytes | None: @@ -124,7 +123,8 @@ def read(n: int = -1) -> bytes | None: file.read = read - if self.skip + self.length > size: + self.length = self.length or max(file_size - self.skip, 0) + if self.skip + self.length > file_size: raise ValueError(f"File is too small (requested to write too much data)") max_length = self.soc.flash_get_size() @@ -156,7 +156,7 @@ def _do_read(self): else: max_length = self.soc.flash_get_size() - self.length = self.length or (max_length - self.offset) + self.length = self.length or max(max_length - self.offset, 0) if self.offset + self.length > max_length: raise ValueError(