diff options
Diffstat (limited to 'utils/regtools/qeditor/regdisplaypanel.cpp')
-rw-r--r-- | utils/regtools/qeditor/regdisplaypanel.cpp | 314 |
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 | |||
9 | QWidget *RegItemEditorCreator::createWidget(QWidget * parent) const | ||
10 | { | ||
11 | return new RegLineEdit(parent); | ||
12 | } | ||
13 | |||
14 | QByteArray RegItemEditorCreator::valuePropertyName () const | ||
15 | { | ||
16 | return QByteArray("text"); | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * DevDisplayPanel | ||
21 | */ | ||
22 | DevDisplayPanel::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 | |||
63 | void DevDisplayPanel::AllowWrite(bool en) | ||
64 | { | ||
65 | Q_UNUSED(en); | ||
66 | } | ||
67 | |||
68 | QWidget *DevDisplayPanel::GetWidget() | ||
69 | { | ||
70 | return this; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * RegDisplayPanel | ||
75 | */ | ||
76 | |||
77 | RegDisplayPanel::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 | |||
216 | RegDisplayPanel::~RegDisplayPanel() | ||
217 | { | ||
218 | delete m_table_edit_factory; | ||
219 | } | ||
220 | |||
221 | void 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 | |||
275 | void 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 | |||
282 | IoBackend::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 | |||
294 | void 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 | |||
310 | QWidget *RegDisplayPanel::GetWidget() | ||
311 | { | ||
312 | return this; | ||
313 | } | ||
314 | |||