summaryrefslogtreecommitdiffstats
path: root/utils/regtools/qeditor/regdisplaypanel.cpp
diff options
context:
space:
mode:
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 @@
+#include "regdisplaypanel.h"
+#include <QHeaderView>
+#include <QDebug>
+
+/**
+ * RegItemEditorCreator
+ */
+
+QWidget *RegItemEditorCreator::createWidget(QWidget * parent) const
+{
+ return new RegLineEdit(parent);
+}
+
+QByteArray RegItemEditorCreator::valuePropertyName () const
+{
+ return QByteArray("text");
+}
+
+/**
+ * DevDisplayPanel
+ */
+DevDisplayPanel::DevDisplayPanel(QWidget *parent, const SocDevRef& dev_ref)
+ :QGroupBox(parent), m_dev(dev_ref), m_reg_font(font())
+{
+ QVBoxLayout *right_layout = new QVBoxLayout;
+ const soc_dev_addr_t& dev_addr = m_dev.GetDevAddr();
+
+ m_reg_font.setWeight(100);
+ m_reg_font.setKerning(false);
+
+ QString dev_name;
+ dev_name.sprintf("HW_%s_BASE", dev_addr.name.c_str());
+
+ QLabel *label_names = new QLabel("<b>" + dev_name + "</b>");
+ label_names->setTextFormat(Qt::RichText);
+
+ QLabel *label_addr = new QLabel("<b>" + QString().sprintf("0x%03x", dev_addr.addr) + "</b>");
+ label_addr->setTextFormat(Qt::RichText);
+
+ QHBoxLayout *top_layout = new QHBoxLayout;
+ top_layout->addStretch();
+ top_layout->addWidget(label_names);
+ top_layout->addWidget(label_addr);
+ top_layout->addStretch();
+
+ m_name = new QLabel(this);
+ m_name->setTextFormat(Qt::RichText);
+ m_name->setText("<h1>" + QString::fromStdString(m_dev.GetDev().long_name) + "</h1>");
+
+ m_desc = new QLabel(this);
+ m_name->setTextFormat(Qt::RichText);
+ m_desc->setText(QString::fromStdString(m_dev.GetDev().desc));
+
+ right_layout->addLayout(top_layout, 0);
+ right_layout->addWidget(m_name, 0);
+ right_layout->addWidget(m_desc, 0);
+ right_layout->addStretch(1);
+
+ setTitle("Device Description");
+ setLayout(right_layout);
+}
+
+void DevDisplayPanel::AllowWrite(bool en)
+{
+ Q_UNUSED(en);
+}
+
+QWidget *DevDisplayPanel::GetWidget()
+{
+ return this;
+}
+
+/**
+ * RegDisplayPanel
+ */
+
+RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref)
+ :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref), m_reg_font(font())
+{
+ bool read_only = m_io_backend->IsReadOnly();
+
+ QVBoxLayout *right_layout = new QVBoxLayout;
+
+ const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
+ const soc_reg_t& reg = m_reg.GetReg();
+ const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
+
+ m_reg_font.setWeight(100);
+ m_reg_font.setKerning(false);
+
+ QString reg_name;
+ reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str());
+ QStringList names;
+ QVector< soc_addr_t > addresses;
+ names.append(reg_name);
+ addresses.append(reg_addr.addr);
+ if(reg.flags & REG_HAS_SCT)
+ {
+ names.append(reg_name + "_SET");
+ names.append(reg_name + "_CLR");
+ names.append(reg_name + "_TOG");
+ addresses.append(reg_addr.addr + 4);
+ addresses.append(reg_addr.addr + 8);
+ addresses.append(reg_addr.addr + 12);
+ }
+
+ QString str;
+ str += "<table align=left>";
+ for(int i = 0; i < names.size(); i++)
+ str += "<tr><td><b>" + names[i] + "</b></td></tr>";
+ str += "</table>";
+ QLabel *label_names = new QLabel;
+ label_names->setTextFormat(Qt::RichText);
+ label_names->setText(str);
+
+ QString str_addr;
+ str_addr += "<table align=left>";
+ for(int i = 0; i < names.size(); i++)
+ str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>";
+ str_addr += "</table>";
+ QLabel *label_addr = new QLabel;
+ label_addr->setTextFormat(Qt::RichText);
+ label_addr->setText(str_addr);
+
+ QHBoxLayout *top_layout = new QHBoxLayout;
+ top_layout->addStretch();
+ top_layout->addWidget(label_names);
+ top_layout->addWidget(label_addr);
+ top_layout->addStretch();
+
+ m_raw_val_name = new QLabel;
+ m_raw_val_name->setText("Raw value:");
+ m_raw_val_edit = new RegLineEdit;
+ m_raw_val_edit->SetReadOnly(read_only);
+ m_raw_val_edit->GetLineEdit()->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
+ m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
+ m_raw_val_edit->GetLineEdit()->setFont(m_reg_font);
+ connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
+ QHBoxLayout *raw_val_layout = new QHBoxLayout;
+ raw_val_layout->addStretch();
+ raw_val_layout->addWidget(m_raw_val_name);
+ raw_val_layout->addWidget(m_raw_val_edit);
+ raw_val_layout->addStretch();
+
+ m_value_table = new GrowingTableWidget;
+ m_value_table->setRowCount(reg.field.size());
+ m_value_table->setColumnCount(5);
+ for(size_t row = 0; row < reg.field.size(); row++)
+ {
+ const soc_reg_field_t& field = reg.field[row];
+ QString bits_str;
+ if(field.first_bit == field.last_bit)
+ bits_str.sprintf("%d", field.first_bit);
+ else
+ bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
+ QTableWidgetItem *item = new QTableWidgetItem(bits_str);
+ item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ m_value_table->setItem(row, 0, item);
+ item = new QTableWidgetItem(QString(field.name.c_str()));
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ m_value_table->setItem(row, 1, item);
+ item = new QTableWidgetItem(QString(field.desc.c_str()));
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ m_value_table->setItem(row, 4, item);
+ }
+ m_value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits"));
+ m_value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
+ m_value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value"));
+ m_value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning"));
+ m_value_table->setHorizontalHeaderItem(4, new QTableWidgetItem("Description"));
+ m_value_table->verticalHeader()->setVisible(false);
+ m_value_table->resizeColumnsToContents();
+ m_value_table->horizontalHeader()->setStretchLastSection(true);
+ m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ m_table_delegate = new QStyledItemDelegate(this);
+ m_table_edit_factory = new QItemEditorFactory();
+ m_regedit_creator = new RegItemEditorCreator();
+ m_table_edit_factory->registerEditor(QVariant::String, m_regedit_creator);
+ m_table_delegate->setItemEditorFactory(m_table_edit_factory);
+ m_value_table->setItemDelegate(m_table_delegate);
+
+ m_sexy_display = new RegSexyDisplay(reg_ref, this);
+ m_sexy_display->setFont(m_reg_font);
+
+ m_desc = new QLabel(this);
+ m_desc->setTextFormat(Qt::RichText);
+ m_desc->setText(QString::fromStdString(m_reg.GetReg().desc));
+
+ right_layout->addWidget(m_desc);
+ right_layout->addLayout(top_layout);
+ if(raw_val_layout)
+ right_layout->addLayout(raw_val_layout);
+ right_layout->addWidget(m_sexy_display);
+ right_layout->addWidget(m_value_table);
+
+ setTitle("Register Description");
+ m_viewport = new QWidget;
+ m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_viewport->setLayout(right_layout);
+ m_scroll = new QScrollArea;
+ m_scroll->setWidget(m_viewport);
+ m_scroll->setWidgetResizable(true);
+ m_scroll->setFrameShape(QFrame::NoFrame);
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->addWidget(m_scroll, 1);
+ setLayout(layout);
+ AllowWrite(false);
+
+ // load data
+ Reload();
+}
+
+RegDisplayPanel::~RegDisplayPanel()
+{
+ delete m_table_edit_factory;
+}
+
+void RegDisplayPanel::Reload()
+{
+ const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
+ const soc_reg_t& reg = m_reg.GetReg();
+ const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
+ soc_word_t value;
+ BackendHelper helper(m_io_backend, m_reg);
+ bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
+
+ if(has_value)
+ {
+ m_raw_val_name->show();
+ m_raw_val_edit->show();
+ m_raw_val_edit->GetLineEdit()->setText(QString().sprintf("0x%08x", value));
+ }
+ else
+ {
+ m_raw_val_name->hide();
+ m_raw_val_edit->hide();
+ }
+
+ int row = 0;
+ foreach(const soc_reg_field_t& field, reg.field)
+ {
+ QTableWidgetItem *item = new QTableWidgetItem();
+ QTableWidgetItem *desc_item = new QTableWidgetItem();
+ if(has_value)
+ {
+ soc_word_t v = (value & field.bitmask()) >> field.first_bit;
+ QString value_name;
+ foreach(const soc_reg_field_value_t& rval, field.value)
+ if(v == rval.value)
+ value_name = rval.name.c_str();
+ const char *fmt = "%lu";
+ // heuristic
+ if((field.last_bit - field.first_bit + 1) > 16)
+ fmt = "0x%lx";
+ item->setText(QString().sprintf(fmt, (unsigned long)v));
+ item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
+
+ if(value_name.size() != 0)
+ {
+ desc_item->setText(value_name);
+ desc_item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
+ }
+ }
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ desc_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ m_value_table->setItem(row, 2, item);
+ m_value_table->setItem(row, 3, desc_item);
+ row++;
+ }
+}
+
+void RegDisplayPanel::AllowWrite(bool en)
+{
+ m_allow_write = en;
+ if(m_raw_val_edit)
+ m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
+}
+
+IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
+{
+ switch(mode)
+ {
+ case RegLineEdit::Write: return IoBackend::Write;
+ case RegLineEdit::Set: return IoBackend::Set;
+ case RegLineEdit::Clear: return IoBackend::Clear;
+ case RegLineEdit::Toggle: return IoBackend::Toggle;
+ default: return IoBackend::Write;
+ }
+}
+
+void RegDisplayPanel::OnRawRegValueReturnPressed()
+{
+ soc_word_t val;
+ QLineEdit *edit = m_raw_val_edit->GetLineEdit();
+ const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator *>(edit->validator());
+ QValidator::State state = validator->parse(edit->text(), val);
+ if(state != QValidator::Acceptable)
+ return;
+ IoBackend::WriteMode mode = EditModeToWriteMode(m_raw_val_edit->GetMode());
+ BackendHelper helper(m_io_backend, m_reg);
+ helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
+ val, mode);
+ // FIXME: we should notify the UI to read value back because it has changed
+ Reload();
+}
+
+QWidget *RegDisplayPanel::GetWidget()
+{
+ return this;
+}
+