summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor/regdisplaypanel.cpp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-04-07 11:28:04 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2014-05-01 19:34:18 +0200
commit4356666101e0e7985e65a19f86bc4a74519e93f9 (patch)
treebf8de8057d93d0fab0a30cae92a90f5a4edc79dc /utils/regtools/qeditor/regdisplaypanel.cpp
parent3754624edc48539c5cc5acbf426ce909477e87d8 (diff)
downloadrockbox-4356666101e0e7985e65a19f86bc4a74519e93f9.tar.gz
rockbox-4356666101e0e7985e65a19f86bc4a74519e93f9.zip
regtools: completely rework qeditor, improve soc desc library and tools
The graphical editor can now display and editor description files. The library has been improved to provide more useful function. The XML format has been slightly changed: only one soc is allowed per file (this is was already de facto the case since <soc> was the root tag). Also introduce a DTD to validate the files. Change-Id: If70ba35b6dc0242bdb87411cf4baee9597798aac
Diffstat (limited to 'utils/regtools/qeditor/regdisplaypanel.cpp')
-rw-r--r--utils/regtools/qeditor/regdisplaypanel.cpp314
1 files changed, 314 insertions, 0 deletions
diff --git a/utils/regtools/qeditor/regdisplaypanel.cpp b/utils/regtools/qeditor/regdisplaypanel.cpp
new file mode 100644
index 0000000000..cef5f9807b
--- /dev/null
+++ b/utils/regtools/qeditor/regdisplaypanel.cpp
@@ -0,0 +1,314 @@
1#include "regdisplaypanel.h"
2#include <QHeaderView>
3#include <QDebug>
4
5/**
6 * RegItemEditorCreator
7 */
8
9QWidget *RegItemEditorCreator::createWidget(QWidget * parent) const
10{
11 return new RegLineEdit(parent);
12}
13
14QByteArray RegItemEditorCreator::valuePropertyName () const
15{
16 return QByteArray("text");
17}
18
19/**
20 * DevDisplayPanel
21 */
22DevDisplayPanel::DevDisplayPanel(QWidget *parent, const SocDevRef& dev_ref)
23 :QGroupBox(parent), m_dev(dev_ref), m_reg_font(font())
24{
25 QVBoxLayout *right_layout = new QVBoxLayout;
26 const soc_dev_addr_t& dev_addr = m_dev.GetDevAddr();
27
28 m_reg_font.setWeight(100);
29 m_reg_font.setKerning(false);
30
31 QString dev_name;
32 dev_name.sprintf("HW_%s_BASE", dev_addr.name.c_str());
33
34 QLabel *label_names = new QLabel("<b>" + dev_name + "</b>");
35 label_names->setTextFormat(Qt::RichText);
36
37 QLabel *label_addr = new QLabel("<b>" + QString().sprintf("0x%03x", dev_addr.addr) + "</b>");
38 label_addr->setTextFormat(Qt::RichText);
39
40 QHBoxLayout *top_layout = new QHBoxLayout;
41 top_layout->addStretch();
42 top_layout->addWidget(label_names);
43 top_layout->addWidget(label_addr);
44 top_layout->addStretch();
45
46 m_name = new QLabel(this);
47 m_name->setTextFormat(Qt::RichText);
48 m_name->setText("<h1>" + QString::fromStdString(m_dev.GetDev().long_name) + "</h1>");
49
50 m_desc = new QLabel(this);
51 m_name->setTextFormat(Qt::RichText);
52 m_desc->setText(QString::fromStdString(m_dev.GetDev().desc));
53
54 right_layout->addLayout(top_layout, 0);
55 right_layout->addWidget(m_name, 0);
56 right_layout->addWidget(m_desc, 0);
57 right_layout->addStretch(1);
58
59 setTitle("Device Description");
60 setLayout(right_layout);
61}
62
63void DevDisplayPanel::AllowWrite(bool en)
64{
65 Q_UNUSED(en);
66}
67
68QWidget *DevDisplayPanel::GetWidget()
69{
70 return this;
71}
72
73/**
74 * RegDisplayPanel
75 */
76
77RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref)
78 :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref), m_reg_font(font())
79{
80 bool read_only = m_io_backend->IsReadOnly();
81
82 QVBoxLayout *right_layout = new QVBoxLayout;
83
84 const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
85 const soc_reg_t& reg = m_reg.GetReg();
86 const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
87
88 m_reg_font.setWeight(100);
89 m_reg_font.setKerning(false);
90
91 QString reg_name;
92 reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str());
93 QStringList names;
94 QVector< soc_addr_t > addresses;
95 names.append(reg_name);
96 addresses.append(reg_addr.addr);
97 if(reg.flags & REG_HAS_SCT)
98 {
99 names.append(reg_name + "_SET");
100 names.append(reg_name + "_CLR");
101 names.append(reg_name + "_TOG");
102 addresses.append(reg_addr.addr + 4);
103 addresses.append(reg_addr.addr + 8);
104 addresses.append(reg_addr.addr + 12);
105 }
106
107 QString str;
108 str += "<table align=left>";
109 for(int i = 0; i < names.size(); i++)
110 str += "<tr><td><b>" + names[i] + "</b></td></tr>";
111 str += "</table>";
112 QLabel *label_names = new QLabel;
113 label_names->setTextFormat(Qt::RichText);
114 label_names->setText(str);
115
116 QString str_addr;
117 str_addr += "<table align=left>";
118 for(int i = 0; i < names.size(); i++)
119 str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>";
120 str_addr += "</table>";
121 QLabel *label_addr = new QLabel;
122 label_addr->setTextFormat(Qt::RichText);
123 label_addr->setText(str_addr);
124
125 QHBoxLayout *top_layout = new QHBoxLayout;
126 top_layout->addStretch();
127 top_layout->addWidget(label_names);
128 top_layout->addWidget(label_addr);
129 top_layout->addStretch();
130
131 m_raw_val_name = new QLabel;
132 m_raw_val_name->setText("Raw value:");
133 m_raw_val_edit = new RegLineEdit;
134 m_raw_val_edit->SetReadOnly(read_only);
135 m_raw_val_edit->GetLineEdit()->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
136 m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
137 m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
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;
141 raw_val_layout->addStretch();
142 raw_val_layout->addWidget(m_raw_val_name);
143 raw_val_layout->addWidget(m_raw_val_edit);
144 raw_val_layout->addStretch();
145
146 m_value_table = new GrowingTableWidget;
147 m_value_table->setRowCount(reg.field.size());
148 m_value_table->setColumnCount(5);
149 for(size_t row = 0; row < reg.field.size(); row++)
150 {
151 const soc_reg_field_t& field = reg.field[row];
152 QString bits_str;
153 if(field.first_bit == field.last_bit)
154 bits_str.sprintf("%d", field.first_bit);
155 else
156 bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
157 QTableWidgetItem *item = new QTableWidgetItem(bits_str);
158 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
159 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
160 m_value_table->setItem(row, 0, item);
161 item = new QTableWidgetItem(QString(field.name.c_str()));
162 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
163 m_value_table->setItem(row, 1, item);
164 item = new QTableWidgetItem(QString(field.desc.c_str()));
165 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
166 m_value_table->setItem(row, 4, item);
167 }
168 m_value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits"));
169 m_value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
170 m_value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value"));
171 m_value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning"));
172 m_value_table->setHorizontalHeaderItem(4, new QTableWidgetItem("Description"));
173 m_value_table->verticalHeader()->setVisible(false);
174 m_value_table->resizeColumnsToContents();
175 m_value_table->horizontalHeader()->setStretchLastSection(true);
176 m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
177
178 m_table_delegate = new QStyledItemDelegate(this);
179 m_table_edit_factory = new QItemEditorFactory();
180 m_regedit_creator = new RegItemEditorCreator();
181 m_table_edit_factory->registerEditor(QVariant::String, m_regedit_creator);
182 m_table_delegate->setItemEditorFactory(m_table_edit_factory);
183 m_value_table->setItemDelegate(m_table_delegate);
184
185 m_sexy_display = new RegSexyDisplay(reg_ref, this);
186 m_sexy_display->setFont(m_reg_font);
187
188 m_desc = new QLabel(this);
189 m_desc->setTextFormat(Qt::RichText);
190 m_desc->setText(QString::fromStdString(m_reg.GetReg().desc));
191
192 right_layout->addWidget(m_desc);
193 right_layout->addLayout(top_layout);
194 if(raw_val_layout)
195 right_layout->addLayout(raw_val_layout);
196 right_layout->addWidget(m_sexy_display);
197 right_layout->addWidget(m_value_table);
198
199 setTitle("Register Description");
200 m_viewport = new QWidget;
201 m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
202 m_viewport->setLayout(right_layout);
203 m_scroll = new QScrollArea;
204 m_scroll->setWidget(m_viewport);
205 m_scroll->setWidgetResizable(true);
206 m_scroll->setFrameShape(QFrame::NoFrame);
207 QHBoxLayout *layout = new QHBoxLayout;
208 layout->addWidget(m_scroll, 1);
209 setLayout(layout);
210 AllowWrite(false);
211
212 // load data
213 Reload();
214}
215
216RegDisplayPanel::~RegDisplayPanel()
217{
218 delete m_table_edit_factory;
219}
220
221void RegDisplayPanel::Reload()
222{
223 const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
224 const soc_reg_t& reg = m_reg.GetReg();
225 const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
226 soc_word_t value;
227 BackendHelper helper(m_io_backend, m_reg);
228 bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
229
230 if(has_value)
231 {
232 m_raw_val_name->show();
233 m_raw_val_edit->show();
234 m_raw_val_edit->GetLineEdit()->setText(QString().sprintf("0x%08x", value));
235 }
236 else
237 {
238 m_raw_val_name->hide();
239 m_raw_val_edit->hide();
240 }
241
242 int row = 0;
243 foreach(const soc_reg_field_t& field, reg.field)
244 {
245 QTableWidgetItem *item = new QTableWidgetItem();
246 QTableWidgetItem *desc_item = new QTableWidgetItem();
247 if(has_value)
248 {
249 soc_word_t v = (value & field.bitmask()) >> field.first_bit;
250 QString value_name;
251 foreach(const soc_reg_field_value_t& rval, field.value)
252 if(v == rval.value)
253 value_name = rval.name.c_str();
254 const char *fmt = "%lu";
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)
262 {
263 desc_item->setText(value_name);
264 desc_item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
265 }
266 }
267 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
268 desc_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
269 m_value_table->setItem(row, 2, item);
270 m_value_table->setItem(row, 3, desc_item);
271 row++;
272 }
273}
274
275void RegDisplayPanel::AllowWrite(bool en)
276{
277 m_allow_write = en;
278 if(m_raw_val_edit)
279 m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
280}
281
282IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
283{
284 switch(mode)
285 {
286 case RegLineEdit::Write: return IoBackend::Write;
287 case RegLineEdit::Set: return IoBackend::Set;
288 case RegLineEdit::Clear: return IoBackend::Clear;
289 case RegLineEdit::Toggle: return IoBackend::Toggle;
290 default: return IoBackend::Write;
291 }
292}
293
294void RegDisplayPanel::OnRawRegValueReturnPressed()
295{
296 soc_word_t val;
297 QLineEdit *edit = m_raw_val_edit->GetLineEdit();
298 const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator *>(edit->validator());
299 QValidator::State state = validator->parse(edit->text(), val);
300 if(state != QValidator::Acceptable)
301 return;
302 IoBackend::WriteMode mode = EditModeToWriteMode(m_raw_val_edit->GetMode());
303 BackendHelper helper(m_io_backend, m_reg);
304 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
305 val, mode);
306 // FIXME: we should notify the UI to read value back because it has changed
307 Reload();
308}
309
310QWidget *RegDisplayPanel::GetWidget()
311{
312 return this;
313}
314