summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-05-11 19:51:55 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2014-05-11 19:56:56 +0200
commit7b590a953639714cf8ea4b550dd7f6558698e23f (patch)
tree4d37890770d45b29237fb671aa66ac446dff7684
parent4c1eafc208426d4457660313314289a570287cb8 (diff)
downloadrockbox-7b590a953639714cf8ea4b550dd7f6558698e23f.tar.gz
rockbox-7b590a953639714cf8ea4b550dd7f6558698e23f.zip
qeditor: many enhancement
Qeditor has been improved in many ways: - it can now dump all registers, just like the lua DUMPER.dump_all() command - several crash were fixed - when connected to a hwstub command, one can correctly edit individual fields - the code was simplified in several places Change-Id: I092b99ce3a12ff6417552de61d62c65f706bcff0
-rw-r--r--utils/regtools/qeditor/aux.cpp54
-rw-r--r--utils/regtools/qeditor/aux.h50
-rw-r--r--utils/regtools/qeditor/backend.cpp45
-rw-r--r--utils/regtools/qeditor/backend.h7
-rw-r--r--utils/regtools/qeditor/regdisplaypanel.cpp89
-rw-r--r--utils/regtools/qeditor/regdisplaypanel.h11
-rw-r--r--utils/regtools/qeditor/regtab.cpp43
-rw-r--r--utils/regtools/qeditor/regtab.h2
8 files changed, 261 insertions, 40 deletions
diff --git a/utils/regtools/qeditor/aux.cpp b/utils/regtools/qeditor/aux.cpp
index 0614bb57f6..de45f6c438 100644
--- a/utils/regtools/qeditor/aux.cpp
+++ b/utils/regtools/qeditor/aux.cpp
@@ -321,6 +321,47 @@ void SocFieldEditor::setField(uint field)
321} 321}
322 322
323/** 323/**
324 * SocFieldCachedItemDelegate
325 */
326
327QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLocale& locale) const
328{
329 // FIXME see QTBUG-30392
330 if(value.type() == QVariant::UserType && value.userType() == qMetaTypeId< SocFieldCachedValue >())
331 {
332 const SocFieldCachedValue& v = value.value< SocFieldCachedValue >();
333 int bitcount = v.field().last_bit - v.field().first_bit;
334 return QString("0x%1").arg(v.value(), (bitcount + 3) / 4, 16, QChar('0'));
335 }
336 else
337 return QStyledItemDelegate::displayText(value, locale);
338}
339
340/**
341 * SocFieldCachedEditor
342 */
343SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent)
344 :SocFieldEditor(soc_reg_field_t(), parent)
345{
346}
347
348SocFieldCachedEditor::~SocFieldCachedEditor()
349{
350}
351
352SocFieldCachedValue SocFieldCachedEditor::value() const
353{
354 return SocFieldCachedValue(m_value.field(), field());
355}
356
357void SocFieldCachedEditor::setValue(SocFieldCachedValue val)
358{
359 m_value = val;
360 SetRegField(m_value.field());
361 setField(m_value.value());
362}
363
364/**
324 * SocFieldEditorCreator 365 * SocFieldEditorCreator
325 */ 366 */
326QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const 367QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const
@@ -334,6 +375,19 @@ QByteArray SocFieldEditorCreator::valuePropertyName() const
334} 375}
335 376
336/** 377/**
378 * SocFieldCachedEditorCreator
379 */
380QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const
381{
382 return new SocFieldCachedEditor(parent);
383}
384
385QByteArray SocFieldCachedEditorCreator::valuePropertyName() const
386{
387 return QByteArray("value");
388}
389
390/**
337 * RegSexyDisplay 391 * RegSexyDisplay
338 */ 392 */
339RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent) 393RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent)
diff --git a/utils/regtools/qeditor/aux.h b/utils/regtools/qeditor/aux.h
index d6a572826c..ee08f1f31b 100644
--- a/utils/regtools/qeditor/aux.h
+++ b/utils/regtools/qeditor/aux.h
@@ -106,6 +106,7 @@ public:
106 106
107 uint field() const; 107 uint field() const;
108 void setField(uint field); 108 void setField(uint field);
109 void SetRegField(const soc_reg_field_t& field) { m_reg_field = field; }
109 110
110protected: 111protected:
111 SocFieldValidator *m_validator; 112 SocFieldValidator *m_validator;
@@ -126,6 +127,55 @@ protected:
126 soc_reg_field_t m_field; 127 soc_reg_field_t m_field;
127}; 128};
128 129
130class SocFieldCachedValue
131{
132public:
133 SocFieldCachedValue():m_value(0) {}
134 SocFieldCachedValue(const soc_reg_field_t& field, uint value)
135 :m_field(field), m_value(value) {}
136 virtual ~SocFieldCachedValue() {}
137 const soc_reg_field_t& field() const { return m_field; }
138 uint value() const { return m_value; }
139protected:
140 soc_reg_field_t m_field;
141 uint m_value;
142};
143
144Q_DECLARE_METATYPE(SocFieldCachedValue)
145
146class SocFieldCachedItemDelegate : public QStyledItemDelegate
147{
148public:
149 SocFieldCachedItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent) {}
150
151 virtual QString displayText(const QVariant& value, const QLocale& locale) const;
152};
153
154class SocFieldCachedEditor : public SocFieldEditor
155{
156 Q_OBJECT
157 Q_PROPERTY(SocFieldCachedValue value READ value WRITE setValue USER true)
158public:
159 SocFieldCachedEditor(QWidget *parent = 0);
160 virtual ~SocFieldCachedEditor();
161
162 SocFieldCachedValue value() const;
163 void setValue(SocFieldCachedValue field);
164protected:
165 SocFieldCachedValue m_value;
166};
167
168class SocFieldCachedEditorCreator : public QItemEditorCreatorBase
169{
170public:
171 SocFieldCachedEditorCreator() {}
172
173 virtual QWidget *createWidget(QWidget *parent) const;
174 virtual QByteArray valuePropertyName() const;
175
176protected:
177};
178
129class RegSexyDisplay : public QWidget 179class RegSexyDisplay : public QWidget
130{ 180{
131 Q_OBJECT 181 Q_OBJECT
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp
index 10ef84c6a0..423b0bb520 100644
--- a/utils/regtools/qeditor/backend.cpp
+++ b/utils/regtools/qeditor/backend.cpp
@@ -90,9 +90,10 @@ IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev)
90 * FileIoBackend 90 * FileIoBackend
91 */ 91 */
92 92
93FileIoBackend::FileIoBackend(const QString& filename) 93FileIoBackend::FileIoBackend(const QString& filename, const QString& soc_name)
94{ 94{
95 m_filename = filename; 95 m_filename = filename;
96 m_soc = soc_name;
96 Reload(); 97 Reload();
97} 98}
98 99
@@ -163,7 +164,7 @@ bool FileIoBackend::Commit()
163 while(it.hasNext()) 164 while(it.hasNext())
164 { 165 {
165 it.next(); 166 it.next();
166 out << it.key() << " = " << it.value() << "\n"; 167 out << it.key() << " = " << hex << showbase << it.value() << "\n";
167 } 168 }
168 out.flush(); 169 out.flush();
169 return file.flush(); 170 return file.flush();
@@ -175,6 +176,16 @@ bool FileIoBackend::Commit()
175 */ 176 */
176HWStubDevice::HWStubDevice(struct libusb_device *dev) 177HWStubDevice::HWStubDevice(struct libusb_device *dev)
177{ 178{
179 Init(dev);
180}
181
182HWStubDevice::HWStubDevice(const HWStubDevice *dev)
183{
184 Init(dev->m_dev);
185}
186
187void HWStubDevice::Init(struct libusb_device *dev)
188{
178 libusb_ref_device(dev); 189 libusb_ref_device(dev);
179 m_dev = dev; 190 m_dev = dev;
180 m_handle = 0; 191 m_handle = 0;
@@ -325,7 +336,7 @@ QString HWStubIoBackend::GetSocName()
325 336
326HWStubIoBackend::~HWStubIoBackend() 337HWStubIoBackend::~HWStubIoBackend()
327{ 338{
328 m_dev->Close(); 339 delete m_dev;
329} 340}
330 341
331bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value) 342bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
@@ -530,3 +541,31 @@ bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg,
530 v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit; 541 v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit;
531 return true; 542 return true;
532} 543}
544
545bool BackendHelper::DumpAllRegisters(const QString& filename)
546{
547 FileIoBackend b(filename, QString::fromStdString(m_soc.GetSoc().name));
548 BackendHelper bh(&b, m_soc);
549 for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++)
550 {
551 const soc_dev_t& dev = m_soc.GetSoc().dev[i];
552 for(size_t j = 0; j < dev.addr.size(); j++)
553 {
554 QString devname = QString::fromStdString(dev.addr[j].name);
555 for(size_t k = 0; k < dev.reg.size(); k++)
556 {
557 const soc_reg_t& reg = dev.reg[k];
558 for(size_t l = 0; l < reg.addr.size(); l++)
559 {
560 QString regname = QString::fromStdString(reg.addr[l].name);
561 soc_word_t val;
562 if(!ReadRegister(devname, regname, val))
563 return false;
564 if(!bh.WriteRegister(devname, regname, val))
565 return false;
566 }
567 }
568 }
569 }
570 return b.Commit();
571}
diff --git a/utils/regtools/qeditor/backend.h b/utils/regtools/qeditor/backend.h
index 9d4c75f0b0..e876e9d286 100644
--- a/utils/regtools/qeditor/backend.h
+++ b/utils/regtools/qeditor/backend.h
@@ -85,7 +85,7 @@ class FileIoBackend : public IoBackend
85{ 85{
86 Q_OBJECT 86 Q_OBJECT
87public: 87public:
88 FileIoBackend(const QString& filename); 88 FileIoBackend(const QString& filename, const QString& soc_name = "");
89 89
90 virtual bool SupportAccess(AccessType type) { return type == ByName; } 90 virtual bool SupportAccess(AccessType type) { return type == ByName; }
91 virtual QString GetSocName(); 91 virtual QString GetSocName();
@@ -113,6 +113,7 @@ class HWStubDevice
113{ 113{
114public: 114public:
115 HWStubDevice(struct libusb_device *dev); 115 HWStubDevice(struct libusb_device *dev);
116 HWStubDevice(const HWStubDevice *dev);
116 ~HWStubDevice(); 117 ~HWStubDevice();
117 bool IsValid(); 118 bool IsValid();
118 bool Open(); 119 bool Open();
@@ -130,6 +131,7 @@ public:
130 131
131protected: 132protected:
132 bool Probe(); 133 bool Probe();
134 void Init(struct libusb_device *dev);
133 135
134 bool m_valid; 136 bool m_valid;
135 struct libusb_device *m_dev; 137 struct libusb_device *m_dev;
@@ -146,6 +148,7 @@ class HWStubIoBackend : public IoBackend
146{ 148{
147 Q_OBJECT 149 Q_OBJECT
148public: 150public:
151 // NOTE: HWStubIoBackend takes ownership of the device and will delete it
149 HWStubIoBackend(HWStubDevice *dev); 152 HWStubIoBackend(HWStubDevice *dev);
150 virtual ~HWStubIoBackend(); 153 virtual ~HWStubIoBackend();
151 154
@@ -310,6 +313,8 @@ public:
310 bool GetRegRef(const SocDevRef& dev, const QString& reg, SocRegRef& ref); 313 bool GetRegRef(const SocDevRef& dev, const QString& reg, SocRegRef& ref);
311 bool GetFieldRef(const SocRegRef& reg, const QString& field, SocFieldRef& ref); 314 bool GetFieldRef(const SocRegRef& reg, const QString& field, SocFieldRef& ref);
312 bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr); 315 bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr);
316 bool DumpAllRegisters(const QString& filename);
317
313private: 318private:
314 IoBackend *m_io_backend; 319 IoBackend *m_io_backend;
315 const SocRef& m_soc; 320 const SocRef& m_soc;
diff --git a/utils/regtools/qeditor/regdisplaypanel.cpp b/utils/regtools/qeditor/regdisplaypanel.cpp
index cef5f9807b..8d7bf582f1 100644
--- a/utils/regtools/qeditor/regdisplaypanel.cpp
+++ b/utils/regtools/qeditor/regdisplaypanel.cpp
@@ -136,7 +136,6 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
136 m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit)); 136 m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
137 m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT)); 137 m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
138 m_raw_val_edit->GetLineEdit()->setFont(m_reg_font); 138 m_raw_val_edit->GetLineEdit()->setFont(m_reg_font);
139 connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
140 QHBoxLayout *raw_val_layout = new QHBoxLayout; 139 QHBoxLayout *raw_val_layout = new QHBoxLayout;
141 raw_val_layout->addStretch(); 140 raw_val_layout->addStretch();
142 raw_val_layout->addWidget(m_raw_val_name); 141 raw_val_layout->addWidget(m_raw_val_name);
@@ -157,28 +156,39 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
157 QTableWidgetItem *item = new QTableWidgetItem(bits_str); 156 QTableWidgetItem *item = new QTableWidgetItem(bits_str);
158 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); 157 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
159 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 158 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
160 m_value_table->setItem(row, 0, item); 159 m_value_table->setItem(row, FieldBitsColumn, item);
161 item = new QTableWidgetItem(QString(field.name.c_str())); 160 item = new QTableWidgetItem(QString(field.name.c_str()));
162 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 161 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
163 m_value_table->setItem(row, 1, item); 162 m_value_table->setItem(row, FieldNameColumn, item);
163 item = new QTableWidgetItem();
164 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
165 item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue()));
166 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
167 m_value_table->setItem(row, FieldValueColumn, item);
168 item = new QTableWidgetItem("");
169 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
170 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
171 m_value_table->setItem(row, FieldMeaningColumn, item);
164 item = new QTableWidgetItem(QString(field.desc.c_str())); 172 item = new QTableWidgetItem(QString(field.desc.c_str()));
165 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 173 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
166 m_value_table->setItem(row, 4, item); 174 m_value_table->setItem(row, FieldDescColumn, item);
167 } 175 }
168 m_value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits")); 176 m_value_table->setHorizontalHeaderItem(FieldBitsColumn, new QTableWidgetItem("Bits"));
169 m_value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); 177 m_value_table->setHorizontalHeaderItem(FieldNameColumn, new QTableWidgetItem("Name"));
170 m_value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); 178 m_value_table->setHorizontalHeaderItem(FieldValueColumn, new QTableWidgetItem("Value"));
171 m_value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning")); 179 m_value_table->setHorizontalHeaderItem(FieldMeaningColumn, new QTableWidgetItem("Meaning"));
172 m_value_table->setHorizontalHeaderItem(4, new QTableWidgetItem("Description")); 180 m_value_table->setHorizontalHeaderItem(FieldDescColumn, new QTableWidgetItem("Description"));
173 m_value_table->verticalHeader()->setVisible(false); 181 m_value_table->verticalHeader()->setVisible(false);
174 m_value_table->resizeColumnsToContents(); 182 m_value_table->resizeColumnsToContents();
175 m_value_table->horizontalHeader()->setStretchLastSection(true); 183 m_value_table->horizontalHeader()->setStretchLastSection(true);
176 m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 184 m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
177 185
178 m_table_delegate = new QStyledItemDelegate(this); 186 SocFieldCachedItemDelegate *m_table_delegate = new SocFieldCachedItemDelegate(this);
179 m_table_edit_factory = new QItemEditorFactory(); 187 m_table_edit_factory = new QItemEditorFactory();
180 m_regedit_creator = new RegItemEditorCreator(); 188 SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator();
181 m_table_edit_factory->registerEditor(QVariant::String, m_regedit_creator); 189 // FIXME see QTBUG-30392
190 m_table_edit_factory->registerEditor((QVariant::Type)qMetaTypeId< SocFieldCachedValue >(),
191 m_table_edit_creator);
182 m_table_delegate->setItemEditorFactory(m_table_edit_factory); 192 m_table_delegate->setItemEditorFactory(m_table_edit_factory);
183 m_value_table->setItemDelegate(m_table_delegate); 193 m_value_table->setItemDelegate(m_table_delegate);
184 194
@@ -209,8 +219,12 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
209 setLayout(layout); 219 setLayout(layout);
210 AllowWrite(false); 220 AllowWrite(false);
211 221
222 m_ignore_cell_change = false;
212 // load data 223 // load data
213 Reload(); 224 Reload();
225
226 connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
227 connect(m_value_table, SIGNAL(cellChanged(int, int)), this, SLOT(OnRegFieldValueChanged(int, int)));
214} 228}
215 229
216RegDisplayPanel::~RegDisplayPanel() 230RegDisplayPanel::~RegDisplayPanel()
@@ -239,11 +253,12 @@ void RegDisplayPanel::Reload()
239 m_raw_val_edit->hide(); 253 m_raw_val_edit->hide();
240 } 254 }
241 255
242 int row = 0; 256 m_ignore_cell_change = true;
243 foreach(const soc_reg_field_t& field, reg.field) 257 for(size_t row = 0; row < reg.field.size(); row++)
244 { 258 {
245 QTableWidgetItem *item = new QTableWidgetItem(); 259 const soc_reg_field_t& field = reg.field[row];
246 QTableWidgetItem *desc_item = new QTableWidgetItem(); 260 QTableWidgetItem *item = m_value_table->item(row, FieldValueColumn);
261 QTableWidgetItem *desc_item = m_value_table->item(row, FieldMeaningColumn);
247 if(has_value) 262 if(has_value)
248 { 263 {
249 soc_word_t v = (value & field.bitmask()) >> field.first_bit; 264 soc_word_t v = (value & field.bitmask()) >> field.first_bit;
@@ -251,25 +266,20 @@ void RegDisplayPanel::Reload()
251 foreach(const soc_reg_field_value_t& rval, field.value) 266 foreach(const soc_reg_field_value_t& rval, field.value)
252 if(v == rval.value) 267 if(v == rval.value)
253 value_name = rval.name.c_str(); 268 value_name = rval.name.c_str();
254 const char *fmt = "%lu"; 269 item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue(field, v)));
255 // heuristic
256 if((field.last_bit - field.first_bit + 1) > 16)
257 fmt = "0x%lx";
258 item->setText(QString().sprintf(fmt, (unsigned long)v));
259 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
260
261 if(value_name.size() != 0) 270 if(value_name.size() != 0)
262 {
263 desc_item->setText(value_name); 271 desc_item->setText(value_name);
264 desc_item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
265 }
266 } 272 }
273 else
274 item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue()));
267 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 275 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
268 desc_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 276 if(m_allow_write)
269 m_value_table->setItem(row, 2, item); 277 item->setFlags(item->flags() | Qt::ItemIsEditable);
270 m_value_table->setItem(row, 3, desc_item);
271 row++;
272 } 278 }
279 m_ignore_cell_change = false;
280
281 m_value_table->resizeColumnsToContents();
282 m_value_table->horizontalHeader()->setStretchLastSection(true);
273} 283}
274 284
275void RegDisplayPanel::AllowWrite(bool en) 285void RegDisplayPanel::AllowWrite(bool en)
@@ -277,6 +287,7 @@ void RegDisplayPanel::AllowWrite(bool en)
277 m_allow_write = en; 287 m_allow_write = en;
278 if(m_raw_val_edit) 288 if(m_raw_val_edit)
279 m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write); 289 m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
290 Reload();
280} 291}
281 292
282IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode) 293IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
@@ -303,7 +314,23 @@ void RegDisplayPanel::OnRawRegValueReturnPressed()
303 BackendHelper helper(m_io_backend, m_reg); 314 BackendHelper helper(m_io_backend, m_reg);
304 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(), 315 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
305 val, mode); 316 val, mode);
306 // FIXME: we should notify the UI to read value back because it has changed 317 Reload();
318}
319
320void RegDisplayPanel::OnRegFieldValueChanged(int row, int col)
321{
322 if(m_ignore_cell_change || col != FieldValueColumn)
323 return;
324 QTableWidgetItem *item = m_value_table->item(row, col);
325 SocFieldCachedValue val = item->data(Qt::DisplayRole).value< SocFieldCachedValue >();
326 BackendHelper helper(m_io_backend, m_reg);
327 soc_word_t regval;
328 if(!helper.ReadRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(), regval))
329 return;
330 regval = (regval & ~val.field().bitmask()) |
331 ((val.value() << val.field().first_bit) & val.field().bitmask());
332 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
333 regval, IoBackend::Write);
307 Reload(); 334 Reload();
308} 335}
309 336
diff --git a/utils/regtools/qeditor/regdisplaypanel.h b/utils/regtools/qeditor/regdisplaypanel.h
index 444f3615f2..b8b9729887 100644
--- a/utils/regtools/qeditor/regdisplaypanel.h
+++ b/utils/regtools/qeditor/regdisplaypanel.h
@@ -55,6 +55,15 @@ public:
55protected: 55protected:
56 IoBackend::WriteMode EditModeToWriteMode(RegLineEdit::EditMode mode); 56 IoBackend::WriteMode EditModeToWriteMode(RegLineEdit::EditMode mode);
57 57
58 enum
59 {
60 FieldBitsColumn = 0,
61 FieldNameColumn = 1,
62 FieldValueColumn = 2,
63 FieldMeaningColumn = 3,
64 FieldDescColumn = 4,
65 };
66
58 IoBackend *m_io_backend; 67 IoBackend *m_io_backend;
59 const SocRegRef& m_reg; 68 const SocRegRef& m_reg;
60 bool m_allow_write; 69 bool m_allow_write;
@@ -69,9 +78,11 @@ protected:
69 QLabel *m_desc; 78 QLabel *m_desc;
70 QWidget *m_viewport; 79 QWidget *m_viewport;
71 QScrollArea *m_scroll; 80 QScrollArea *m_scroll;
81 bool m_ignore_cell_change;
72 82
73private slots: 83private slots:
74 void OnRawRegValueReturnPressed(); 84 void OnRawRegValueReturnPressed();
85 void OnRegFieldValueChanged(int row, int col);
75}; 86};
76 87
77#endif /* REGDISPLAYPANEL_H */ 88#endif /* REGDISPLAYPANEL_H */
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp
index 568d859c0e..a335475e48 100644
--- a/utils/regtools/qeditor/regtab.cpp
+++ b/utils/regtools/qeditor/regtab.cpp
@@ -5,6 +5,7 @@
5#include <QFileDialog> 5#include <QFileDialog>
6#include <QDebug> 6#include <QDebug>
7#include <QStyle> 7#include <QStyle>
8#include <QMessageBox>
8#include "backend.h" 9#include "backend.h"
9#include "analyser.h" 10#include "analyser.h"
10#include "regdisplaypanel.h" 11#include "regdisplaypanel.h"
@@ -111,9 +112,11 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
111 m_readonly_check = new QCheckBox("Read-only"); 112 m_readonly_check = new QCheckBox("Read-only");
112 m_readonly_check->setCheckState(Qt::Checked); 113 m_readonly_check->setCheckState(Qt::Checked);
113 m_data_soc_label = new QLabel; 114 m_data_soc_label = new QLabel;
114 QPushButton *data_sel_reload = new QPushButton; 115 m_dump = new QPushButton("Dump", this);
115 data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); 116 m_dump->setIcon(QIcon::fromTheme("system-run"));
116 data_sel_reload->setToolTip("Reload data"); 117 m_data_sel_reload = new QPushButton(this);
118 m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
119 m_data_sel_reload->setToolTip("Reload data");
117 data_sel_layout->addWidget(m_data_selector); 120 data_sel_layout->addWidget(m_data_selector);
118 data_sel_layout->addWidget(m_data_sel_edit, 1); 121 data_sel_layout->addWidget(m_data_sel_edit, 1);
119 data_sel_layout->addStretch(0); 122 data_sel_layout->addStretch(0);
@@ -123,7 +126,8 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
123#endif 126#endif
124 data_sel_layout->addWidget(m_readonly_check); 127 data_sel_layout->addWidget(m_readonly_check);
125 data_sel_layout->addWidget(m_data_soc_label); 128 data_sel_layout->addWidget(m_data_soc_label);
126 data_sel_layout->addWidget(data_sel_reload); 129 data_sel_layout->addWidget(m_dump);
130 data_sel_layout->addWidget(m_data_sel_reload);
127 data_sel_group->setLayout(data_sel_layout); 131 data_sel_group->setLayout(data_sel_layout);
128 m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); 132 m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
129 133
@@ -153,6 +157,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
153 this, SLOT(OnDevChanged(int))); 157 this, SLOT(OnDevChanged(int)));
154#endif 158#endif
155 connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool))); 159 connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool)));
160 connect(m_dump, SIGNAL(clicked(bool)), this, SLOT(OnDumpRegs(bool)));
156 161
157 OnSocListChanged(); 162 OnSocListChanged();
158 OnDataSelChanged(0); 163 OnDataSelChanged(0);
@@ -205,6 +210,8 @@ void RegTab::OnDataSelChanged(int index)
205 m_dev_selector->hide(); 210 m_dev_selector->hide();
206#endif 211#endif
207 m_readonly_check->show(); 212 m_readonly_check->show();
213 m_data_sel_reload->show();
214 m_dump->hide();
208 QFileDialog *fd = new QFileDialog(m_data_selector); 215 QFileDialog *fd = new QFileDialog(m_data_selector);
209 fd->setFilter("Textual files (*.txt);;All files (*)"); 216 fd->setFilter("Textual files (*.txt);;All files (*)");
210 fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString()); 217 fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString());
@@ -226,6 +233,8 @@ void RegTab::OnDataSelChanged(int index)
226 m_data_sel_edit->hide(); 233 m_data_sel_edit->hide();
227 m_readonly_check->show(); 234 m_readonly_check->show();
228 m_dev_selector->show(); 235 m_dev_selector->show();
236 m_data_sel_reload->hide();
237 m_dump->show();
229 OnDevListChanged(); 238 OnDevListChanged();
230 } 239 }
231#endif 240#endif
@@ -236,6 +245,8 @@ void RegTab::OnDataSelChanged(int index)
236 m_dev_selector->hide(); 245 m_dev_selector->hide();
237#endif 246#endif
238 m_readonly_check->hide(); 247 m_readonly_check->hide();
248 m_data_sel_reload->hide();
249 m_dump->hide();
239 250
240 delete m_io_backend; 251 delete m_io_backend;
241 m_io_backend = m_backend->CreateDummyIoBackend(); 252 m_io_backend = m_backend->CreateDummyIoBackend();
@@ -363,7 +374,10 @@ void RegTab::OnDevChanged(int index)
363 return; 374 return;
364 HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >()); 375 HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >());
365 delete m_io_backend; 376 delete m_io_backend;
366 m_io_backend = m_backend->CreateHWStubIoBackend(dev); 377 /* NOTE: make a copy of the HWStubDevice device because the one in the list
378 * might get destroyed when clearing the list while the backend is still
379 * active: this would result in a double free when the backend is also destroyed */
380 m_io_backend = m_backend->CreateHWStubIoBackend(new HWStubDevice(dev));
367 SetDataSocName(m_io_backend->GetSocName()); 381 SetDataSocName(m_io_backend->GetSocName());
368 OnDataSocActivated(m_io_backend->GetSocName()); 382 OnDataSocActivated(m_io_backend->GetSocName());
369 OnDataChanged(); 383 OnDataChanged();
@@ -435,3 +449,22 @@ void RegTab::OnReadOnlyClicked(bool checked)
435 m_right_content->AllowWrite(!checked); 449 m_right_content->AllowWrite(!checked);
436 UpdateSocFilename(); 450 UpdateSocFilename();
437} 451}
452
453void RegTab::OnDumpRegs(bool c)
454{
455 Q_UNUSED(c);
456 QFileDialog *fd = new QFileDialog(this);
457 fd->setAcceptMode(QFileDialog::AcceptSave);
458 fd->setFilter("Textual files (*.txt);;All files (*)");
459 fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString());
460 if(!fd->exec())
461 return;
462 QStringList filenames = fd->selectedFiles();
463 Settings::Get()->setValue("loaddatadir", fd->directory().absolutePath());
464 BackendHelper bh(m_io_backend, m_cur_soc);
465 if(!bh.DumpAllRegisters(filenames[0]))
466 {
467 QMessageBox::warning(this, "The register dump was not saved",
468 "There was an error when dumping the registers");
469 }
470}
diff --git a/utils/regtools/qeditor/regtab.h b/utils/regtools/qeditor/regtab.h
index 78a10ba379..b5b1f56775 100644
--- a/utils/regtools/qeditor/regtab.h
+++ b/utils/regtools/qeditor/regtab.h
@@ -80,6 +80,7 @@ protected:
80 QCheckBox *m_readonly_check; 80 QCheckBox *m_readonly_check;
81 QLabel *m_data_soc_label; 81 QLabel *m_data_soc_label;
82 QPushButton *m_data_sel_reload; 82 QPushButton *m_data_sel_reload;
83 QPushButton *m_dump;
83 QComboBox *m_data_selector; 84 QComboBox *m_data_selector;
84 IoBackend *m_io_backend; 85 IoBackend *m_io_backend;
85 QTabWidget *m_type_selector; 86 QTabWidget *m_type_selector;
@@ -102,6 +103,7 @@ private slots:
102 void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); 103 void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous);
103 void OnAnalyserClicked(QListWidgetItem *clicked); 104 void OnAnalyserClicked(QListWidgetItem *clicked);
104 void OnReadOnlyClicked(bool); 105 void OnReadOnlyClicked(bool);
106 void OnDumpRegs(bool);
105}; 107};
106 108
107#endif /* REGTAB_H */ \ No newline at end of file 109#endif /* REGTAB_H */ \ No newline at end of file