blob: 3dbdb54241f70e9c7151f49074e488b484d24517 [file] [log] [blame]
Amaury Poulyfe1fed82014-09-26 10:46:48 +02001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Amaury Pouly43566662014-04-07 11:28:04 +020021#include "regdisplaypanel.h"
22#include <QHeaderView>
23#include <QDebug>
24
25/**
26 * RegItemEditorCreator
27 */
28
29QWidget *RegItemEditorCreator::createWidget(QWidget * parent) const
30{
31 return new RegLineEdit(parent);
32}
33
34QByteArray RegItemEditorCreator::valuePropertyName () const
35{
36 return QByteArray("text");
37}
38
39/**
Amaury Poulyef0299c2014-08-09 18:39:45 +020040 * SocDisplayPanel
41 */
42SocDisplayPanel::SocDisplayPanel(QWidget *parent, const SocRef& dev_ref)
43 :QGroupBox(parent), m_soc(dev_ref)
44{
45 QVBoxLayout *right_layout = new QVBoxLayout;
46
47 m_name = new QLabel(this);
48 m_name->setTextFormat(Qt::RichText);
49 m_name->setText("<h1>" + QString::fromStdString(m_soc.GetSoc().name) + "</h1>");
50
51 m_desc = new QLabel(this);
52 m_name->setTextFormat(Qt::RichText);
53 m_desc->setText(QString::fromStdString(m_soc.GetSoc().desc));
54
55 right_layout->addWidget(m_name, 0);
56 right_layout->addWidget(m_desc, 0);
57 right_layout->addStretch(1);
58
59 setTitle("System-on-Chip Description");
60 setLayout(right_layout);
61}
62
63void SocDisplayPanel::AllowWrite(bool en)
64{
65 Q_UNUSED(en);
66}
67
68QWidget *SocDisplayPanel::GetWidget()
69{
70 return this;
71}
72
73/**
Amaury Pouly43566662014-04-07 11:28:04 +020074 * DevDisplayPanel
75 */
76DevDisplayPanel::DevDisplayPanel(QWidget *parent, const SocDevRef& dev_ref)
77 :QGroupBox(parent), m_dev(dev_ref), m_reg_font(font())
78{
79 QVBoxLayout *right_layout = new QVBoxLayout;
80 const soc_dev_addr_t& dev_addr = m_dev.GetDevAddr();
81
82 m_reg_font.setWeight(100);
83 m_reg_font.setKerning(false);
84
85 QString dev_name;
86 dev_name.sprintf("HW_%s_BASE", dev_addr.name.c_str());
87
88 QLabel *label_names = new QLabel("<b>" + dev_name + "</b>");
89 label_names->setTextFormat(Qt::RichText);
90
91 QLabel *label_addr = new QLabel("<b>" + QString().sprintf("0x%03x", dev_addr.addr) + "</b>");
92 label_addr->setTextFormat(Qt::RichText);
93
94 QHBoxLayout *top_layout = new QHBoxLayout;
95 top_layout->addStretch();
96 top_layout->addWidget(label_names);
97 top_layout->addWidget(label_addr);
98 top_layout->addStretch();
99
100 m_name = new QLabel(this);
101 m_name->setTextFormat(Qt::RichText);
102 m_name->setText("<h1>" + QString::fromStdString(m_dev.GetDev().long_name) + "</h1>");
103
104 m_desc = new QLabel(this);
105 m_name->setTextFormat(Qt::RichText);
106 m_desc->setText(QString::fromStdString(m_dev.GetDev().desc));
107
Amaury Pouly43566662014-04-07 11:28:04 +0200108 right_layout->addWidget(m_name, 0);
Amaury Poulyef0299c2014-08-09 18:39:45 +0200109 right_layout->addLayout(top_layout, 0);
Amaury Pouly43566662014-04-07 11:28:04 +0200110 right_layout->addWidget(m_desc, 0);
111 right_layout->addStretch(1);
112
113 setTitle("Device Description");
114 setLayout(right_layout);
115}
116
117void DevDisplayPanel::AllowWrite(bool en)
118{
119 Q_UNUSED(en);
120}
121
122QWidget *DevDisplayPanel::GetWidget()
123{
124 return this;
125}
126
127/**
128 * RegDisplayPanel
129 */
130
131RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref)
132 :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref), m_reg_font(font())
133{
134 bool read_only = m_io_backend->IsReadOnly();
135
136 QVBoxLayout *right_layout = new QVBoxLayout;
137
138 const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
139 const soc_reg_t& reg = m_reg.GetReg();
140 const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
141
142 m_reg_font.setWeight(100);
143 m_reg_font.setKerning(false);
144
145 QString reg_name;
146 reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str());
147 QStringList names;
148 QVector< soc_addr_t > addresses;
149 names.append(reg_name);
150 addresses.append(reg_addr.addr);
151 if(reg.flags & REG_HAS_SCT)
152 {
153 names.append(reg_name + "_SET");
154 names.append(reg_name + "_CLR");
155 names.append(reg_name + "_TOG");
156 addresses.append(reg_addr.addr + 4);
157 addresses.append(reg_addr.addr + 8);
158 addresses.append(reg_addr.addr + 12);
159 }
160
161 QString str;
162 str += "<table align=left>";
163 for(int i = 0; i < names.size(); i++)
164 str += "<tr><td><b>" + names[i] + "</b></td></tr>";
165 str += "</table>";
166 QLabel *label_names = new QLabel;
167 label_names->setTextFormat(Qt::RichText);
168 label_names->setText(str);
169
170 QString str_addr;
171 str_addr += "<table align=left>";
172 for(int i = 0; i < names.size(); i++)
173 str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>";
174 str_addr += "</table>";
175 QLabel *label_addr = new QLabel;
176 label_addr->setTextFormat(Qt::RichText);
177 label_addr->setText(str_addr);
178
179 QHBoxLayout *top_layout = new QHBoxLayout;
180 top_layout->addStretch();
181 top_layout->addWidget(label_names);
182 top_layout->addWidget(label_addr);
183 top_layout->addStretch();
184
185 m_raw_val_name = new QLabel;
186 m_raw_val_name->setText("Raw value:");
187 m_raw_val_edit = new RegLineEdit;
188 m_raw_val_edit->SetReadOnly(read_only);
189 m_raw_val_edit->GetLineEdit()->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
190 m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
191 m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
192 m_raw_val_edit->GetLineEdit()->setFont(m_reg_font);
Amaury Pouly43566662014-04-07 11:28:04 +0200193 QHBoxLayout *raw_val_layout = new QHBoxLayout;
194 raw_val_layout->addStretch();
195 raw_val_layout->addWidget(m_raw_val_name);
196 raw_val_layout->addWidget(m_raw_val_edit);
197 raw_val_layout->addStretch();
198
Amaury Pouly5dab7682014-10-22 18:00:59 +0200199 m_value_table = new GrowingTableView;
200 m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
201 m_value_model->SetRegister(m_reg.GetReg());
202 m_value_model->SetReadOnly(read_only);
203 m_value_table->setModel(m_value_model);
Amaury Pouly43566662014-04-07 11:28:04 +0200204 m_value_table->verticalHeader()->setVisible(false);
205 m_value_table->resizeColumnsToContents();
206 m_value_table->horizontalHeader()->setStretchLastSection(true);
207 m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
Amaury Pouly5dab7682014-10-22 18:00:59 +0200208 // FIXME we cannot use setAlternatingRowColors() because we override the
209 // background color, should it be part of the model ?
Amaury Pouly43566662014-04-07 11:28:04 +0200210
Amaury Pouly7b590a92014-05-11 19:51:55 +0200211 SocFieldCachedItemDelegate *m_table_delegate = new SocFieldCachedItemDelegate(this);
Amaury Pouly43566662014-04-07 11:28:04 +0200212 m_table_edit_factory = new QItemEditorFactory();
Amaury Pouly7b590a92014-05-11 19:51:55 +0200213 SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator();
214 // FIXME see QTBUG-30392
215 m_table_edit_factory->registerEditor((QVariant::Type)qMetaTypeId< SocFieldCachedValue >(),
216 m_table_edit_creator);
Amaury Pouly43566662014-04-07 11:28:04 +0200217 m_table_delegate->setItemEditorFactory(m_table_edit_factory);
218 m_value_table->setItemDelegate(m_table_delegate);
219
220 m_sexy_display = new RegSexyDisplay(reg_ref, this);
221 m_sexy_display->setFont(m_reg_font);
222
223 m_desc = new QLabel(this);
224 m_desc->setTextFormat(Qt::RichText);
225 m_desc->setText(QString::fromStdString(m_reg.GetReg().desc));
226
227 right_layout->addWidget(m_desc);
228 right_layout->addLayout(top_layout);
229 if(raw_val_layout)
230 right_layout->addLayout(raw_val_layout);
231 right_layout->addWidget(m_sexy_display);
232 right_layout->addWidget(m_value_table);
233
234 setTitle("Register Description");
235 m_viewport = new QWidget;
236 m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
237 m_viewport->setLayout(right_layout);
238 m_scroll = new QScrollArea;
239 m_scroll->setWidget(m_viewport);
240 m_scroll->setWidgetResizable(true);
241 m_scroll->setFrameShape(QFrame::NoFrame);
242 QHBoxLayout *layout = new QHBoxLayout;
243 layout->addWidget(m_scroll, 1);
244 setLayout(layout);
245 AllowWrite(false);
246
247 // load data
248 Reload();
Amaury Pouly7b590a92014-05-11 19:51:55 +0200249
Amaury Pouly5dab7682014-10-22 18:00:59 +0200250 connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this,
251 SLOT(OnRawRegValueReturnPressed()));
252 connect(m_value_table->model(), SIGNAL(OnValueModified(int)), this,
253 SLOT(OnRegValueChanged(int)));
Amaury Pouly43566662014-04-07 11:28:04 +0200254}
255
256RegDisplayPanel::~RegDisplayPanel()
257{
258 delete m_table_edit_factory;
259}
260
261void RegDisplayPanel::Reload()
262{
263 const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
264 const soc_reg_t& reg = m_reg.GetReg();
265 const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
266 soc_word_t value;
267 BackendHelper helper(m_io_backend, m_reg);
268 bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
269
270 if(has_value)
271 {
272 m_raw_val_name->show();
273 m_raw_val_edit->show();
274 m_raw_val_edit->GetLineEdit()->setText(QString().sprintf("0x%08x", value));
Amaury Pouly5dab7682014-10-22 18:00:59 +0200275 m_value_model->SetValues(QVector< QVariant >(1, QVariant(value)));
Amaury Pouly43566662014-04-07 11:28:04 +0200276 }
277 else
278 {
279 m_raw_val_name->hide();
280 m_raw_val_edit->hide();
Amaury Pouly5dab7682014-10-22 18:00:59 +0200281 m_value_model->SetValues(QVector< QVariant >());
Amaury Pouly43566662014-04-07 11:28:04 +0200282 }
283
Amaury Pouly7b590a92014-05-11 19:51:55 +0200284 m_value_table->resizeColumnsToContents();
285 m_value_table->horizontalHeader()->setStretchLastSection(true);
Amaury Pouly43566662014-04-07 11:28:04 +0200286}
287
288void RegDisplayPanel::AllowWrite(bool en)
289{
290 m_allow_write = en;
291 if(m_raw_val_edit)
Amaury Pouly5dab7682014-10-22 18:00:59 +0200292 {
Amaury Pouly43566662014-04-07 11:28:04 +0200293 m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
Amaury Pouly5dab7682014-10-22 18:00:59 +0200294 m_value_model->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
295 }
Amaury Pouly7b590a92014-05-11 19:51:55 +0200296 Reload();
Amaury Pouly43566662014-04-07 11:28:04 +0200297}
298
299IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
300{
301 switch(mode)
302 {
303 case RegLineEdit::Write: return IoBackend::Write;
304 case RegLineEdit::Set: return IoBackend::Set;
305 case RegLineEdit::Clear: return IoBackend::Clear;
306 case RegLineEdit::Toggle: return IoBackend::Toggle;
307 default: return IoBackend::Write;
308 }
309}
310
311void RegDisplayPanel::OnRawRegValueReturnPressed()
312{
313 soc_word_t val;
314 QLineEdit *edit = m_raw_val_edit->GetLineEdit();
315 const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator *>(edit->validator());
316 QValidator::State state = validator->parse(edit->text(), val);
317 if(state != QValidator::Acceptable)
318 return;
319 IoBackend::WriteMode mode = EditModeToWriteMode(m_raw_val_edit->GetMode());
320 BackendHelper helper(m_io_backend, m_reg);
321 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
322 val, mode);
Amaury Pouly5dab7682014-10-22 18:00:59 +0200323 // register write can change all fields
Amaury Pouly7b590a92014-05-11 19:51:55 +0200324 Reload();
325}
326
Amaury Pouly5dab7682014-10-22 18:00:59 +0200327void RegDisplayPanel::OnRegValueChanged(int index)
Amaury Pouly7b590a92014-05-11 19:51:55 +0200328{
Amaury Pouly5dab7682014-10-22 18:00:59 +0200329 QVariant var = m_value_model->GetValue(index);
330 if(!var.isValid())
Amaury Pouly7b590a92014-05-11 19:51:55 +0200331 return;
Amaury Pouly7b590a92014-05-11 19:51:55 +0200332 BackendHelper helper(m_io_backend, m_reg);
Amaury Pouly7b590a92014-05-11 19:51:55 +0200333 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
Amaury Pouly5dab7682014-10-22 18:00:59 +0200334 var.value< soc_word_t >(), IoBackend::Write);
335 // register write can change all fields
Amaury Pouly43566662014-04-07 11:28:04 +0200336 Reload();
337}
338
339QWidget *RegDisplayPanel::GetWidget()
340{
341 return this;
342}
343