diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-05-11 19:51:55 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2014-05-11 19:56:56 +0200 |
commit | 7b590a953639714cf8ea4b550dd7f6558698e23f (patch) | |
tree | 4d37890770d45b29237fb671aa66ac446dff7684 | |
parent | 4c1eafc208426d4457660313314289a570287cb8 (diff) | |
download | rockbox-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.cpp | 54 | ||||
-rw-r--r-- | utils/regtools/qeditor/aux.h | 50 | ||||
-rw-r--r-- | utils/regtools/qeditor/backend.cpp | 45 | ||||
-rw-r--r-- | utils/regtools/qeditor/backend.h | 7 | ||||
-rw-r--r-- | utils/regtools/qeditor/regdisplaypanel.cpp | 89 | ||||
-rw-r--r-- | utils/regtools/qeditor/regdisplaypanel.h | 11 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 43 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.h | 2 |
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 | |||
327 | QString 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 | */ | ||
343 | SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent) | ||
344 | :SocFieldEditor(soc_reg_field_t(), parent) | ||
345 | { | ||
346 | } | ||
347 | |||
348 | SocFieldCachedEditor::~SocFieldCachedEditor() | ||
349 | { | ||
350 | } | ||
351 | |||
352 | SocFieldCachedValue SocFieldCachedEditor::value() const | ||
353 | { | ||
354 | return SocFieldCachedValue(m_value.field(), field()); | ||
355 | } | ||
356 | |||
357 | void 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 | */ |
326 | QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const | 367 | QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const |
@@ -334,6 +375,19 @@ QByteArray SocFieldEditorCreator::valuePropertyName() const | |||
334 | } | 375 | } |
335 | 376 | ||
336 | /** | 377 | /** |
378 | * SocFieldCachedEditorCreator | ||
379 | */ | ||
380 | QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const | ||
381 | { | ||
382 | return new SocFieldCachedEditor(parent); | ||
383 | } | ||
384 | |||
385 | QByteArray SocFieldCachedEditorCreator::valuePropertyName() const | ||
386 | { | ||
387 | return QByteArray("value"); | ||
388 | } | ||
389 | |||
390 | /** | ||
337 | * RegSexyDisplay | 391 | * RegSexyDisplay |
338 | */ | 392 | */ |
339 | RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent) | 393 | RegSexyDisplay::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 | ||
110 | protected: | 111 | protected: |
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 | ||
130 | class SocFieldCachedValue | ||
131 | { | ||
132 | public: | ||
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; } | ||
139 | protected: | ||
140 | soc_reg_field_t m_field; | ||
141 | uint m_value; | ||
142 | }; | ||
143 | |||
144 | Q_DECLARE_METATYPE(SocFieldCachedValue) | ||
145 | |||
146 | class SocFieldCachedItemDelegate : public QStyledItemDelegate | ||
147 | { | ||
148 | public: | ||
149 | SocFieldCachedItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent) {} | ||
150 | |||
151 | virtual QString displayText(const QVariant& value, const QLocale& locale) const; | ||
152 | }; | ||
153 | |||
154 | class SocFieldCachedEditor : public SocFieldEditor | ||
155 | { | ||
156 | Q_OBJECT | ||
157 | Q_PROPERTY(SocFieldCachedValue value READ value WRITE setValue USER true) | ||
158 | public: | ||
159 | SocFieldCachedEditor(QWidget *parent = 0); | ||
160 | virtual ~SocFieldCachedEditor(); | ||
161 | |||
162 | SocFieldCachedValue value() const; | ||
163 | void setValue(SocFieldCachedValue field); | ||
164 | protected: | ||
165 | SocFieldCachedValue m_value; | ||
166 | }; | ||
167 | |||
168 | class SocFieldCachedEditorCreator : public QItemEditorCreatorBase | ||
169 | { | ||
170 | public: | ||
171 | SocFieldCachedEditorCreator() {} | ||
172 | |||
173 | virtual QWidget *createWidget(QWidget *parent) const; | ||
174 | virtual QByteArray valuePropertyName() const; | ||
175 | |||
176 | protected: | ||
177 | }; | ||
178 | |||
129 | class RegSexyDisplay : public QWidget | 179 | class 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 | ||
93 | FileIoBackend::FileIoBackend(const QString& filename) | 93 | FileIoBackend::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 | */ |
176 | HWStubDevice::HWStubDevice(struct libusb_device *dev) | 177 | HWStubDevice::HWStubDevice(struct libusb_device *dev) |
177 | { | 178 | { |
179 | Init(dev); | ||
180 | } | ||
181 | |||
182 | HWStubDevice::HWStubDevice(const HWStubDevice *dev) | ||
183 | { | ||
184 | Init(dev->m_dev); | ||
185 | } | ||
186 | |||
187 | void 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 | ||
326 | HWStubIoBackend::~HWStubIoBackend() | 337 | HWStubIoBackend::~HWStubIoBackend() |
327 | { | 338 | { |
328 | m_dev->Close(); | 339 | delete m_dev; |
329 | } | 340 | } |
330 | 341 | ||
331 | bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value) | 342 | bool 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 | |||
545 | bool 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 |
87 | public: | 87 | public: |
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 | { |
114 | public: | 114 | public: |
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 | ||
131 | protected: | 132 | protected: |
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 |
148 | public: | 150 | public: |
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 | |||
313 | private: | 318 | private: |
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 | ||
216 | RegDisplayPanel::~RegDisplayPanel() | 230 | RegDisplayPanel::~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 | ||
275 | void RegDisplayPanel::AllowWrite(bool en) | 285 | void 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 | ||
282 | IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode) | 293 | IoBackend::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 | |||
320 | void 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: | |||
55 | protected: | 55 | protected: |
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 | ||
73 | private slots: | 83 | private 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 | |||
453 | void 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 |