Ask for which fuse if needed

If loading a single-byte file (no '%' in filename pattern, and
not an ELF file), ask for which fuse to load.

When saving or programming, make sure to only handle interesting
values. Users can clear a fuse data entry to have this fuse skipped.
This commit is contained in:
Joerg Wunsch
2024-04-02 22:18:01 +02:00
parent 86de67f05f
commit 48bbd4b160
2 changed files with 151 additions and 2 deletions

View File

@@ -286,7 +286,7 @@ class adgui(QObject):
srcdir = str(p.parent)
for f in [ "adgui.ui", "about.ui", "device.ui",
"devinfo.ui", "loglevel.ui", "programmer.ui",
"memories.ui" ]:
"memories.ui", "askfuse.ui" ]:
ui = QFile(srcdir + '/' + f)
if not ui.open(QFile.ReadOnly):
print(f"Cannot open {f}: {ui.errorString()}", file = sys.stderr)
@@ -1004,6 +1004,7 @@ class adgui(QObject):
# make all fuse labels and entries invisible
for w in self.memories.groupBox_13.children():
w.setVisible(False)
w.clear()
def fuse_names(self):
# return name of fuse memories for self.dev
@@ -1027,6 +1028,11 @@ class adgui(QObject):
idx = 0
self.fuselabels = {}
for name in fuses:
# self.fuselabels has the fuse name as key, and a list of
# [idx, allocated] as data. 'idx' is the GUI index for the
# fuseN and fvalN label and lineedit, respectively.
# 'allocated' is a flag indicating that there is
# "interesting" data in the lineedit entry.
self.fuselabels[name] = [idx, False]
eval(f"self.memories.fuse{idx}.setText({'name'})")
eval(f"self.memories.fuse{idx}.setVisible(True)")
@@ -1105,6 +1111,11 @@ class adgui(QObject):
self.log(f"Could not find {fuse} memory", ad.MSG_ERROR)
return
t = le.text()
if t.isspace():
m.clear(m.size)
self.fuselabels[fuse][1] = False
self.log(f"Cleared {fuse} field", ad.MSG_DEBUG)
return
try:
val = int(t, 16)
except ValueError as e:
@@ -1124,7 +1135,7 @@ class adgui(QObject):
continue
slotnumber = self.fuselabels[fuse][0]
val = eval(f"self.memories.fval{slotnumber}.text()")
if val == '':
if val.isspace():
self.log(f"Not programming {fuse} memory: no value", ad.MSG_DEBUG)
continue
if not self.fuselabels[fuse][1]:
@@ -1160,6 +1171,9 @@ class adgui(QObject):
self.log("Internal error: cannot determine file format", ad.MSG_ERROR)
return
for fuse in self.fuselabels.keys():
if not self.fuselabels[fuse][1]:
# empty field, skip
continue
m = ad.avr_locate_mem(self.dev, fuse)
if not m:
self.log(f"Could not find {fuse} memory", ad.MSG_ERROR)
@@ -1175,6 +1189,15 @@ class adgui(QObject):
amnt = ad.fileio(ad.FIO_WRITE, fname, fmt, self.dev, fuse, m.size)
self.log(f"Wrote {amnt} bytes of {fuse} to {fname}")
def fuse_ask(self):
self.askfuse.fuse_selection.clear()
for fuse in self.fuselabels.keys():
self.askfuse.fuse_selection.addItem(fuse)
result = self.askfuse.exec()
if result == QDialog.Accepted:
return self.askfuse.fuse_selection.currentText()
return None
def fuses_load(self):
if self.memories.fuse_ffAuto.isChecked():
fmt = ad.FMT_AUTO
@@ -1189,6 +1212,38 @@ class adgui(QObject):
else:
self.log("Internal error: cannot determine file format", ad.MSG_ERROR)
return
if self.fusename.find('%') == -1:
# If absolute name, see whether it is ELF or something
# else. ELF can contain data for all fuses, all other
# file formats only contain data for a single fuse, so we
# must ask for which one it is intended.
p = pathlib.Path(self.fusename)
if p.is_file():
if fmt == ad.FMT_AUTO:
fmt = ad.fileio_fmt_autodetect(fname)
if fmt == ad.FMT_ELF:
# OK, assume multi-fuse
pass
else:
# Ask
fname = self.fusename
fuse = self.fuse_ask()
if fuse:
m = ad.avr_locate_mem(self.dev, fuse)
if not m:
self.log(f"Could not find {fuse} memory", ad.MSG_ERROR)
return
amnt = ad.fileio(ad.FIO_READ, fname, fmt, self.dev, fuse, -1)
self.log(f"Read {amnt} bytes of {fuse} from {fname}")
if amnt > 0:
val = int(m.get(1)[0])
s = f"{val:02X}"
(idx, allocated) = self.fuselabels[fuse]
eval(f"self.memories.fval{idx}.clear()")
eval(f"self.memories.fval{idx}.insert('{s}')")
self.fuselabels[fuse][1] = True
return
# proceed with attempting to load all fuses here
for fuse in self.fuselabels.keys():
m = ad.avr_locate_mem(self.dev, fuse)
if not m:

94
src/python/askfuse.ui Normal file
View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>askfuse</class>
<widget class="QDialog" name="askfuse">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>395</width>
<height>182</height>
</rect>
</property>
<property name="windowTitle">
<string>Which fuse?</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>130</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>361</width>
<height>101</height>
</rect>
</property>
<property name="title">
<string>Which fuse to load?</string>
</property>
<widget class="QComboBox" name="fuse_selection">
<property name="geometry">
<rect>
<x>90</x>
<y>50</y>
<width>171</width>
<height>25</height>
</rect>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>askfuse</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>askfuse</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>