1
0
Fork 0
forked from len0rd/rockbox

regtoosl/qeditor: port to the new description format

This big commit port qeditor from v1 to v2 register file format. Although
the display code was much simplified, the edit code had to be rewritten.
The new code also brings many improvement to the register display widget.

The new code also compiles with both Qt4 and Qt5, although it is recommended
to use Qt5 to get some improvements, especially in the layout of editor.

Change-Id: I24633ac37a144f25d9e705b565654269ec9cfbd3
This commit is contained in:
Amaury Pouly 2016-02-06 15:08:43 +00:00
parent 0f701a64be
commit 6b9610fb90
18 changed files with 2968 additions and 1964 deletions

View file

@ -20,7 +20,7 @@
****************************************************************************/
#include "analyser.h"
Analyser::Analyser(const SocRef& soc, IoBackend *backend)
Analyser::Analyser(const soc_desc::soc_ref_t& soc, IoBackend *backend)
:m_soc(soc), m_io_backend(backend)
{
}

View file

@ -30,13 +30,13 @@
class Analyser : public RegTabPanel
{
public:
Analyser(const SocRef& soc, IoBackend *backend);
Analyser(const soc_desc::soc_ref_t& soc, IoBackend *backend);
virtual ~Analyser();
virtual void AllowWrite(bool en) { Q_UNUSED(en); }
virtual QWidget *GetWidget() = 0;
protected:
const SocRef& m_soc;
soc_desc::soc_ref_t m_soc;
IoBackend *m_io_backend;
};
@ -49,7 +49,7 @@ public:
virtual QString GetName() = 0;
virtual bool SupportSoc(const QString& soc_name) = 0;
// return NULL of soc is not handled by the analyser
virtual Analyser *Create(const SocRef& soc, IoBackend *backend) = 0;
virtual Analyser *Create(const soc_desc::soc_ref_t& soc, IoBackend *backend) = 0;
private:
QString m_name;
@ -72,9 +72,9 @@ public:
virtual QString GetName() { return m_name; }
virtual bool SupportSoc(const QString& soc_name) { return T::SupportSoc(soc_name); }
// return NULL of soc is not handled by the analyser
virtual T *Create(const SocRef& soc, IoBackend *backend)
virtual T *Create(const soc_desc::soc_ref_t& soc, IoBackend *backend)
{
if(!T::SupportSoc(soc.GetSoc().name.c_str()))
if(!T::SupportSoc(QString::fromStdString(soc.get()->name)))
return 0;
return new T(soc, backend);
}

View file

@ -28,15 +28,15 @@
* SocFile
*/
SocFile::SocFile()
:m_valid(false)
:m_valid(true)
{
}
SocFile::SocFile(const QString& filename)
:m_filename(filename)
{
m_valid = parse_xml(filename.toStdString(), m_soc);
normalize(m_soc);
soc_desc::error_context_t ctx;
m_valid = soc_desc::parse_xml(filename.toStdString(), m_soc, ctx);
}
bool SocFile::IsValid()
@ -44,9 +44,12 @@ bool SocFile::IsValid()
return m_valid;
}
SocRef SocFile::GetSocRef()
soc_desc::soc_ref_t SocFile::GetSocRef()
{
return SocRef(this);
if(m_valid)
return soc_desc::soc_ref_t(&m_soc);
else
return soc_desc::soc_ref_t();
}
QString SocFile::GetFilename()
@ -67,15 +70,22 @@ QList< SocFileRef > Backend::GetSocFileList()
{
QList< SocFileRef > list;
for(std::list< SocFile >::iterator it = m_socs.begin(); it != m_socs.end(); ++it)
list.append(SocFileRef(&(*it)));
{
if(it->IsValid())
list.append(SocFileRef(&(*it)));
}
return list;
}
QList< SocRef > Backend::GetSocList()
QList< soc_desc::soc_ref_t > Backend::GetSocList()
{
QList< SocRef > list;
QList< soc_desc::soc_ref_t > list;
for(std::list< SocFile >::iterator it = m_socs.begin(); it != m_socs.end(); ++it)
list.append(it->GetSocRef());
{
soc_desc::soc_ref_t r = it->GetSocRef();
if(r.valid())
list.append(r);
}
return list;
}
@ -85,7 +95,7 @@ bool Backend::LoadSocDesc(const QString& filename)
if(!f.IsValid())
return false;
m_socs.push_back(f);
emit OnSocListChanged();
emit OnSocAdded(SocFileRef(&m_socs.back()));
return true;
}
@ -106,6 +116,63 @@ IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev)
}
#endif
/**
* DummyIoBackend
*/
DummyIoBackend::DummyIoBackend()
{
}
bool DummyIoBackend::IsValid()
{
return false;
}
QString DummyIoBackend::GetSocName()
{
return "";
}
bool DummyIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value,
unsigned width)
{
Q_UNUSED(addr);
Q_UNUSED(value);
Q_UNUSED(width);
return false;
}
bool DummyIoBackend::Reload()
{
return false;
}
bool DummyIoBackend::IsReadOnly()
{
return true;
}
bool DummyIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value,
unsigned width, WriteMode mode)
{
Q_UNUSED(addr);
Q_UNUSED(value);
Q_UNUSED(mode);
Q_UNUSED(width);
return false;
}
bool DummyIoBackend::IsDirty()
{
return false;
}
bool DummyIoBackend::Commit()
{
return false;
}
/**
* RamIoBackend
*/
@ -114,9 +181,36 @@ RamIoBackend::RamIoBackend(const QString& soc_name)
m_soc = soc_name;
}
bool RamIoBackend::ReadRegister(const QString& name, soc_word_t& value)
bool RamIoBackend::IsValid()
{
QMap<QString, soc_word_t>::const_iterator it = m_map.find(name);
return m_soc != "";
}
QString RamIoBackend::GetSocName()
{
return m_soc;
}
void RamIoBackend::SetSocName(const QString& soc_name)
{
m_soc = soc_name;
}
bool RamIoBackend::RamIoBackend::Reload()
{
return false;
}
bool RamIoBackend::IsReadOnly()
{
return false;
}
bool RamIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value,
unsigned width)
{
Q_UNUSED(width);
QMap<soc_addr_t, soc_word_t>::const_iterator it = m_map.find(addr);
if(it == m_map.end())
return false;
value = it.value();
@ -128,19 +222,29 @@ void RamIoBackend::DeleteAll()
m_map.clear();
}
bool RamIoBackend::WriteRegister(const QString& name, soc_word_t value, WriteMode mode)
bool RamIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value,
unsigned width, WriteMode mode)
{
Q_UNUSED(width);
switch(mode)
{
case Write: m_map[name] = value; return true;
case Set: m_map[name] |= value; return true;
case Clear: m_map[name] &= ~value; return true;
case Toggle: m_map[name] ^= value; return true;
case Write: m_map[addr] = value; return true;
case Set: m_map[addr] |= value; return true;
case Clear: m_map[addr] &= ~value; return true;
case Toggle: m_map[addr] ^= value; return true;
default: return false;
}
}
bool RamIoBackend::IsDirty()
{
return false;
}
bool RamIoBackend::Commit()
{
return false;
}
/**
* FileIoBackend
@ -154,6 +258,10 @@ FileIoBackend::FileIoBackend(const QString& filename, const QString& soc_name)
Reload();
}
bool FileIoBackend::IsValid()
{
return m_valid;
}
bool FileIoBackend::Reload()
{
@ -170,25 +278,27 @@ bool FileIoBackend::Reload()
int idx = line.indexOf('=');
if(idx == -1)
continue;
QString key = line.left(idx).trimmed();
bool ok;
soc_word_t val = line.mid(idx + 1).trimmed().toULong(&ok, 0);
if(key == "HW")
m_soc = line.mid(idx + 1).trimmed();
else if(ok)
RamIoBackend::WriteRegister(key, val, Write);
QString key_str = line.left(idx).trimmed();
QString val_str = line.mid(idx + 1).trimmed();
bool key_ok,val_ok;
soc_word_t val = val_str.toULong(&val_ok, 0);
soc_word_t key = key_str.toULong(&key_ok, 0);
if(key_str == "soc")
m_soc = val_str;
else if(key_ok && val_ok)
RamIoBackend::WriteRegister(key, val, 32, Write);
}
m_readonly = !QFileInfo(file).isWritable();
m_dirty = false;
m_valid = true;
return true;
}
bool FileIoBackend::WriteRegister(const QString& name, soc_word_t value, WriteMode mode)
bool FileIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value,
unsigned width, WriteMode mode)
{
m_dirty = true;
return RamIoBackend::WriteRegister(name, value, mode);
return RamIoBackend::WriteRegister(addr, value, width, mode);
}
bool FileIoBackend::Commit()
@ -199,17 +309,32 @@ bool FileIoBackend::Commit()
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
return false;
QTextStream out(&file);
out << "HW = " << m_soc << "\n";
QMapIterator< QString, soc_word_t > it(m_map);
out << "soc = " << m_soc << "\n";
QMapIterator< soc_addr_t, soc_word_t > it(m_map);
while(it.hasNext())
{
it.next();
out << it.key() << " = " << hex << showbase << it.value() << "\n";
out << hex << showbase << it.key() << " = " << hex << showbase << it.value() << "\n";
}
out.flush();
return file.flush();
}
bool FileIoBackend::IsReadOnly()
{
return m_readonly;
}
bool FileIoBackend::IsDirty()
{
return m_dirty;
}
QString FileIoBackend::GetFileName()
{
return m_filename;
}
#ifdef HAVE_HWSTUB
/**
* HWStubDevice
@ -355,6 +480,8 @@ HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev)
else
m_soc = QString("pp%1").arg(pp.wChipID, 4, 16, QChar('0'));
}
else if(target.dID == HWSTUB_TARGET_ATJ)
m_soc = "atj213x";
else
m_soc = target.bName;
}
@ -369,13 +496,44 @@ HWStubIoBackend::~HWStubIoBackend()
delete m_dev;
}
bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
bool HWStubIoBackend::IsValid()
{
return m_dev->ReadMem(addr, sizeof(value), &value);
return m_dev->IsValid();
}
bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode mode)
bool HWStubIoBackend::IsReadOnly()
{
return false;
}
bool HWStubIoBackend::IsDirty()
{
return false;
}
bool HWStubIoBackend::Commit()
{
return true;
}
HWStubDevice *HWStubIoBackend::GetDevice()
{
return m_dev;
}
bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value,
unsigned width)
{
if(width != 8 && width != 16 && width != 32)
return false;
return m_dev->ReadMem(addr, width / 8, &value);
}
bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value,
unsigned width, WriteMode mode)
{
if(width != 8 && width != 16 && width != 32)
return false;
switch(mode)
{
case Set: addr += 4; break;
@ -383,7 +541,7 @@ bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode
case Toggle: addr += 12; break;
default: break;
}
return m_dev->WriteMem(addr, sizeof(value), &value);
return m_dev->WriteMem(addr, width / 8, &value);
}
bool HWStubIoBackend::Reload()
@ -486,146 +644,146 @@ lib_usb_init __lib_usb_init;
* BackendHelper
*/
BackendHelper::BackendHelper(IoBackend *io_backend, const SocRef& soc)
BackendHelper::BackendHelper(IoBackend *io_backend, const soc_desc::soc_ref_t& soc)
:m_io_backend(io_backend), m_soc(soc)
{
}
bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v)
QString BackendHelper::GetPath(const soc_desc::node_inst_t& inst)
{
if(m_io_backend->SupportAccess(IoBackend::ByName))
return m_io_backend->ReadRegister("HW." + dev + "." + reg, v);
if(m_io_backend->SupportAccess(IoBackend::ByAddress))
{
soc_addr_t addr;
if(GetRegisterAddress(dev, reg, addr))
return m_io_backend->ReadRegister(addr, v);
}
return false;
if(!inst.valid() || inst.is_root())
return QString();
QString s = GetPath(inst.parent());
if(!s.isEmpty())
s += ".";
s += inst.name().c_str();
if(inst.is_indexed())
s = QString("%1[%2]").arg(s).arg(inst.index());
return s;
}
bool BackendHelper::WriteRegister(const QString& dev, const QString& reg,
soc_desc::node_inst_t BackendHelper::ParsePath(const QString& path)
{
soc_desc::node_inst_t inst = m_soc.root_inst();
/* empty path is root */
if(path.isEmpty())
return inst;
int pos = 0;
while(pos < path.size())
{
/* try to find the next separator */
int next = path.indexOf('.', pos);
if(next == -1)
next = path.size();
/* try to find the index, if any */
int lidx = path.indexOf('[', pos);
if(lidx == -1 || lidx > next)
lidx = next;
/* extract name */
std::string name = path.mid(pos, lidx - pos).toStdString();
/* and index */
if(lidx < next)
{
int ridx = path.indexOf(']', lidx + 1);
/* syntax error ? */
if(ridx == -1 || ridx > next)
return soc_desc::node_inst_t();
/* invalid number ? */
bool ok = false;
size_t idx = path.mid(lidx + 1, ridx - lidx - 1).toUInt(&ok);
if(ok)
inst = inst.child(name, idx);
else
inst = soc_desc::node_inst_t();
}
else
inst = inst.child(name);
/* advance right after the separator */
pos = next + 1;
}
return inst;
}
bool BackendHelper::ReadRegister(const soc_desc::node_inst_t& inst,
soc_word_t& v)
{
soc_addr_t addr;
if(!GetRegisterAddress(inst, addr))
return false;
return m_io_backend->ReadRegister(addr, v, inst.node().reg().get()->width);
}
bool BackendHelper::WriteRegister(const soc_desc::node_inst_t& inst,
soc_word_t v, IoBackend::WriteMode mode)
{
if(m_io_backend->SupportAccess(IoBackend::ByName))
return m_io_backend->WriteRegister("HW." + dev + "." + reg, v, mode);
if(m_io_backend->SupportAccess(IoBackend::ByAddress))
{
soc_addr_t addr;
if(GetRegisterAddress(dev, reg, addr))
return m_io_backend->WriteRegister(addr, v, mode);
}
return false;
soc_addr_t addr;
if(!GetRegisterAddress(inst, addr))
return false;
return m_io_backend->WriteRegister(addr, v, inst.node().reg().get()->width, mode);
}
bool BackendHelper::GetDevRef(const QString& sdev, SocDevRef& ref)
{
for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++)
{
const soc_dev_t& dev = m_soc.GetSoc().dev[i];
for(size_t j = 0; j < dev.addr.size(); j++)
if(dev.addr[j].name.c_str() == sdev)
{
ref = SocDevRef(m_soc, i, j);
return true;
}
}
return false;
}
bool BackendHelper::GetRegRef(const SocDevRef& dev, const QString& sreg, SocRegRef& ref)
{
const soc_dev_t& sdev = dev.GetDev();
for(size_t i = 0; i < sdev.reg.size(); i++)
{
const soc_reg_t& reg = sdev.reg[i];
for(size_t j = 0; j < reg.addr.size(); j++)
{
if(reg.addr[j].name.c_str() == sreg)
{
ref = SocRegRef(dev, i, j);
return true;
}
}
}
return false;
}
bool BackendHelper::GetFieldRef(const SocRegRef& reg, const QString& sfield, SocFieldRef& ref)
{
for(size_t i = 0; i < reg.GetReg().field.size(); i++)
if(reg.GetReg().field[i].name.c_str() == sfield)
{
ref = SocFieldRef(reg, i);
return true;
}
return false;
}
bool BackendHelper::GetRegisterAddress(const QString& dev, const QString& reg,
bool BackendHelper::GetRegisterAddress(const soc_desc::node_inst_t& inst,
soc_addr_t& addr)
{
SocDevRef dev_ref;
SocRegRef reg_ref;
if(!GetDevRef(dev, dev_ref) || !GetRegRef(dev_ref, reg, reg_ref))
if(!inst.valid())
return false;
addr = dev_ref.GetDevAddr().addr + reg_ref.GetRegAddr().addr;
addr = inst.addr();
return true;
}
bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg,
bool BackendHelper::ReadRegisterField(const soc_desc::node_inst_t& inst,
const QString& field, soc_word_t& v)
{
SocDevRef dev_ref;
SocRegRef reg_ref;
SocFieldRef field_ref;
if(!GetDevRef(dev, dev_ref) || !GetRegRef(dev_ref, reg, reg_ref) ||
!GetFieldRef(reg_ref, field, field_ref))
soc_desc::field_ref_t ref = inst.node().reg().field(field.toStdString());
if(!ref.valid())
return false;
if(!ReadRegister(dev, reg, v))
if(!ReadRegister(inst, v))
return false;
v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit;
v = (v & ref.get()->bitmask()) >> ref.get()->pos;
return true;
}
bool BackendHelper::DumpAllRegisters(const QString& filename, bool ignore_errors)
{
FileIoBackend b(filename, QString::fromStdString(m_soc.GetSoc().name));
FileIoBackend b(filename, QString::fromStdString(m_soc.get()->name));
bool ret = DumpAllRegisters(&b, ignore_errors);
return ret && b.Commit();
}
bool BackendHelper::DumpAllRegisters(IoBackend *backend, bool ignore_errors)
{
BackendHelper bh(backend, m_soc);
BackendHelper helper(backend, m_soc);
return DumpAllRegisters(&helper, m_soc.root_inst(), ignore_errors);
}
bool BackendHelper::DumpAllRegisters(BackendHelper *bh,
const soc_desc::node_inst_t& inst, bool ignore_errors)
{
bool ret = true;
for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++)
if(inst.node().reg().valid())
{
const soc_dev_t& dev = m_soc.GetSoc().dev[i];
for(size_t j = 0; j < dev.addr.size(); j++)
soc_word_t val;
if(!ReadRegister(inst, val))
{
QString devname = QString::fromStdString(dev.addr[j].name);
for(size_t k = 0; k < dev.reg.size(); k++)
{
const soc_reg_t& reg = dev.reg[k];
for(size_t l = 0; l < reg.addr.size(); l++)
{
QString regname = QString::fromStdString(reg.addr[l].name);
soc_word_t val;
if(!ReadRegister(devname, regname, val))
{
ret = false;
if(!ignore_errors)
return false;
}
else if(!bh.WriteRegister(devname, regname, val))
{
ret = false;
if(!ignore_errors)
return false;
}
}
}
ret = false;
if(!ignore_errors)
return false;
}
else if(!bh->WriteRegister(inst, val))
{
ret = false;
if(!ignore_errors)
return false;
}
}
std::vector< soc_desc::node_inst_t > list = inst.children();
for(size_t i = 0; i < list.size(); i++)
{
if(!DumpAllRegisters(bh, list[i], ignore_errors))
{
ret = false;
if(!ignore_errors)
return false;
}
}
return ret;

View file

@ -26,14 +26,17 @@
#include <QMap>
#include <QVector>
#include <QMetaType>
#include <QAbstractItemModel>
#ifdef HAVE_HWSTUB
#include "hwstub.h"
#endif
#include "soc_desc_v1.hpp"
#include "soc_desc.hpp"
/* we don't want to import the entire soc_desc except for a few selected
* pieces */
using namespace soc_desc_v1;
using soc_desc::soc_word_t;
using soc_desc::soc_addr_t;
using soc_desc::soc_id_t;
class IoBackend : public QObject
{
@ -47,35 +50,20 @@ public:
Write, Set, Clear, Toggle
};
enum AccessType
{
ByName,
ByAddress,
};
/** Register naming convention: name based access are of the form:
* HW.dev.reg
* where <dev> is the device name (including index like APPUART1)
* and <reg> is the register name (including index like PRIORITY29) */
/* report whether backend is valid */
virtual bool IsValid() = 0;
/* report whether backend supports register access type */
virtual bool SupportAccess(AccessType type) = 0;
/* get SoC name */
virtual QString GetSocName() = 0;
/* read a register by name or address */
virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0;
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) = 0;
/* read a register */
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value, unsigned width) = 0;
/* reload content (if it makes sense) */
virtual bool Reload() = 0;
/* check whether backend supports writing */
virtual bool IsReadOnly() = 0;
/* write a register by name or address
* NOTE: even on a read-only backend, a write is allowed be successful as long
* NOTE: even on a read-only backend, a write is allowed to be successful as long
* as commit fails */
virtual bool WriteRegister(const QString& name, soc_word_t value,
WriteMode mode = Write) = 0;
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value,
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, unsigned width,
WriteMode mode = Write) = 0;
/* check whether backend contains uncommitted (ie cached) writes */
virtual bool IsDirty() = 0;
@ -87,23 +75,17 @@ class DummyIoBackend : public IoBackend
{
Q_OBJECT
public:
DummyIoBackend() {}
DummyIoBackend();
virtual bool IsValid() { return false; }
virtual bool SupportAccess(AccessType type) { Q_UNUSED(type); return false; }
virtual QString GetSocName() { return ""; }
virtual bool ReadRegister(const QString& name, soc_word_t& value)
{ Q_UNUSED(name); Q_UNUSED(value); return false; }
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
{ Q_UNUSED(addr); Q_UNUSED(value); return false; }
virtual bool Reload() { return false; }
virtual bool IsReadOnly() { return true; }
virtual bool WriteRegister(const QString& name, soc_word_t value, WriteMode mode)
{ Q_UNUSED(name); Q_UNUSED(value); Q_UNUSED(mode); return false; }
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode mode)
{ Q_UNUSED(addr); Q_UNUSED(value); Q_UNUSED(mode); return false; }
virtual bool IsDirty() { return false; }
virtual bool Commit() { return false; }
virtual bool IsValid();
virtual QString GetSocName();
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value, unsigned width);
virtual bool Reload();
virtual bool IsReadOnly();
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, unsigned width,
WriteMode mode);
virtual bool IsDirty();
virtual bool Commit();
};
/** The RAM backend doesn't have any backend storage and stores all values in
@ -114,26 +96,22 @@ class RamIoBackend : public IoBackend
public:
RamIoBackend(const QString& soc_name = "");
virtual bool IsValid() { return m_soc != ""; }
virtual bool SupportAccess(AccessType type) { return type == ByName; }
virtual QString GetSocName() { return m_soc; }
virtual void SetSocName(const QString& soc_name) { m_soc = soc_name; }
virtual bool ReadRegister(const QString& name, soc_word_t& value);
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
{ Q_UNUSED(addr); Q_UNUSED(value); return false; }
virtual bool Reload() { return false; }
virtual bool IsReadOnly() { return false; }
virtual bool WriteRegister(const QString& name, soc_word_t value, WriteMode mode);
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode mode)
{ Q_UNUSED(addr); Q_UNUSED(value); Q_UNUSED(mode); return false; }
virtual bool IsDirty() { return false; }
virtual bool Commit() { return false; }
virtual bool IsValid();
virtual QString GetSocName();
virtual void SetSocName(const QString& soc_name);
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value, unsigned width);
virtual bool Reload();
virtual bool IsReadOnly();
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, unsigned width,
WriteMode mode);
virtual bool IsDirty();
virtual bool Commit();
/* clear all entries of the backend */
virtual void DeleteAll();
protected:
QString m_soc;
QMap< QString, soc_word_t > m_map;
QMap< soc_addr_t, soc_word_t > m_map;
};
/** NOTE the File backend makes a difference between writes and commits:
@ -144,14 +122,14 @@ class FileIoBackend : public RamIoBackend
public:
FileIoBackend(const QString& filename, const QString& soc_name = "");
virtual bool IsValid() { return m_valid; }
virtual bool SupportAccess(AccessType type) { return type == ByName; }
virtual bool IsValid();
virtual bool Reload();
virtual bool IsReadOnly() { return m_readonly; }
virtual bool WriteRegister(const QString& name, soc_word_t value, WriteMode mode);
virtual bool IsDirty() { return m_dirty; }
virtual bool IsReadOnly();
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, unsigned width,
WriteMode mode);
virtual bool IsDirty();
virtual bool Commit();
QString GetFileName() { return m_filename; }
QString GetFileName();
protected:
QString m_filename;
@ -204,20 +182,16 @@ public:
HWStubIoBackend(HWStubDevice *dev);
virtual ~HWStubIoBackend();
virtual bool IsValid() { return m_dev->IsValid(); }
virtual bool SupportAccess(AccessType type) { return type == ByAddress; }
virtual bool IsValid();
virtual QString GetSocName();
virtual bool ReadRegister(const QString& name, soc_word_t& value)
{ Q_UNUSED(name); Q_UNUSED(value); return false; }
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value);
virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value, unsigned width);
virtual bool Reload();
virtual bool IsReadOnly() { return false; }
virtual bool WriteRegister(const QString& name, soc_word_t value, WriteMode mode)
{ Q_UNUSED(name); Q_UNUSED(value); Q_UNUSED(mode); return false; }
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode mode);
virtual bool IsDirty() { return false; }
virtual bool Commit() { return true; }
HWStubDevice *GetDevice() { return m_dev; }
virtual bool IsReadOnly();
virtual bool WriteRegister(soc_addr_t addr, soc_word_t value, unsigned width,
WriteMode mode);
virtual bool IsDirty();
virtual bool Commit();
HWStubDevice *GetDevice();
protected:
QString m_soc;
@ -251,8 +225,6 @@ protected:
};
#endif
class SocRef;
class SocFile
{
public:
@ -260,14 +232,14 @@ public:
SocFile(const QString& filename);
bool IsValid();
SocRef GetSocRef();
soc_desc::soc_ref_t GetSocRef();
QString GetFilename();
soc_t& GetSoc() { return m_soc; }
soc_desc::soc_t& GetSoc() { return m_soc; }
protected:
bool m_valid;
QString m_filename;
soc_t m_soc;
soc_desc::soc_t m_soc;
};
class SocFileRef
@ -283,56 +255,17 @@ protected:
Q_DECLARE_METATYPE(SocFileRef)
class SocRef : public SocFileRef
{
public:
SocRef() {}
SocRef(SocFile *file):SocFileRef(file) {}
soc_t& GetSoc() const { return GetSocFile()->GetSoc(); }
};
Q_DECLARE_METATYPE(soc_desc::instance_t::type_t)
Q_DECLARE_METATYPE(soc_desc::range_t::type_t)
Q_DECLARE_METATYPE(SocRef)
class SocDevRef : public SocRef
{
public:
SocDevRef() {}
SocDevRef(const SocRef& soc, int dev_idx, int dev_addr_idx)
:SocRef(soc), m_dev_idx(dev_idx), m_dev_addr_idx(dev_addr_idx) {}
int GetDevIndex() const { return m_dev_idx; }
soc_dev_t& GetDev() const { return GetSoc().dev[GetDevIndex()]; }
int GetDevAddrIndex() const { return m_dev_addr_idx; }
soc_dev_addr_t& GetDevAddr() const { return GetDev().addr[GetDevAddrIndex()]; }
protected:
int m_dev_idx, m_dev_addr_idx;
};
class SocRegRef : public SocDevRef
{
public:
SocRegRef() {}
SocRegRef(const SocDevRef& dev, int reg_idx, int reg_addr_idx)
:SocDevRef(dev), m_reg_idx(reg_idx), m_reg_addr_idx(reg_addr_idx) {}
int GetRegIndex() const { return m_reg_idx; }
soc_reg_t& GetReg() const { return GetDev().reg[GetRegIndex()]; }
int GetRegAddrIndex() const { return m_reg_addr_idx; }
soc_reg_addr_t& GetRegAddr() const { return GetReg().addr[GetRegAddrIndex()]; }
protected:
int m_reg_idx, m_reg_addr_idx;
};
class SocFieldRef : public SocRegRef
{
public:
SocFieldRef(){}
SocFieldRef(const SocRegRef& reg, int field_idx)
:SocRegRef(reg), m_field_idx(field_idx) {}
int GetFieldIndex() const { return m_field_idx; }
soc_reg_field_t& GetField() const { return GetReg().field[GetFieldIndex()]; }
protected:
int m_field_idx;
};
Q_DECLARE_METATYPE(soc_desc::soc_ref_t)
Q_DECLARE_METATYPE(soc_desc::node_ref_t)
Q_DECLARE_METATYPE(soc_desc::register_ref_t)
Q_DECLARE_METATYPE(soc_desc::field_ref_t)
Q_DECLARE_METATYPE(soc_desc::node_inst_t)
/** NOTE the Backend stores soc descriptions in a way that pointers are never
* invalidated */
class Backend : public QObject
{
Q_OBJECT
@ -340,7 +273,7 @@ public:
Backend();
QList< SocFileRef > GetSocFileList();
QList< SocRef > GetSocList();
QList< soc_desc::soc_ref_t > GetSocList();
bool LoadSocDesc(const QString& filename);
IoBackend *CreateDummyIoBackend();
IoBackend *CreateFileIoBackend(const QString& filename);
@ -349,33 +282,38 @@ public:
#endif
signals:
void OnSocListChanged();
void OnSocAdded(const SocFileRef& ref);
private:
/* store them as a list so that pointers are never invalidated */
std::list< SocFile > m_socs;
};
class BackendHelper
{
public:
BackendHelper(IoBackend *io_backend, const SocRef& soc);
bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v);
bool ReadRegisterField(const QString& dev, const QString& reg,
BackendHelper(IoBackend *io_backend, const soc_desc::soc_ref_t& soc);
QString GetPath(const soc_desc::node_inst_t& inst);
soc_desc::node_inst_t ParsePath(const QString& path);
bool ReadRegister(const soc_desc::node_inst_t& inst, soc_word_t& v);
bool ReadRegisterField(const soc_desc::node_inst_t& inst,
const QString& field, soc_word_t& v);
bool WriteRegister(const QString& dev, const QString& reg, soc_word_t v,
bool WriteRegister(const soc_desc::node_inst_t& inst, soc_word_t v,
IoBackend::WriteMode mode = IoBackend::Write);
bool GetDevRef(const QString& dev, SocDevRef& ref);
bool GetRegRef(const SocDevRef& dev, const QString& reg, SocRegRef& ref);
bool GetFieldRef(const SocRegRef& reg, const QString& field, SocFieldRef& ref);
bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr);
bool GetRegisterAddress(const soc_desc::node_inst_t& inst, soc_addr_t& addr);
/* NOTE: does not commit writes to the backend
* if ignore_errors is true, the dump will continue even on errors, and the
* function will return false if one or more errors occured */
bool DumpAllRegisters(IoBackend *backend, bool ignore_errors = true);
bool DumpAllRegisters(const QString& filename, bool ignore_errors = true);
protected:
bool DumpAllRegisters(BackendHelper *bh, const soc_desc::node_inst_t& inst,
bool ignore_errors);
private:
IoBackend *m_io_backend;
const SocRef& m_soc;
const soc_desc::soc_ref_t& m_soc;
};
#endif /* __BACKEND_H__ */

View file

@ -20,12 +20,22 @@
****************************************************************************/
#include <QApplication>
#include <QDir>
#include <QTextCodec>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setApplicationVersion(APP_VERSION);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
/** NOTE: Qt4 only
* use the locale codec as the C-string codec, otherwise QString::toStdString()
* performs as toLatin1() which breaks conversion on virtually all systems.
* FIXME The documentation mentions that the C-string codec should produce ASCII
* compatible (ie 7-bit) encodings but nowadays most system are using UTF-8
* so I don't see why this is a problem */
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
#endif
Backend backend;;
QDir dir(QCoreApplication::applicationDirPath());
@ -47,4 +57,4 @@ int main(int argc, char *argv[])
MainWindow win(&backend);
win.show();
return app.exec();
}
}

View file

@ -43,7 +43,7 @@ void DocumentTab::OnModified(bool modified)
m_tab->SetTabModified(this, modified);
}
void DocumentTab::SetTabWidget(MyTabWidget *tab)
void DocumentTab::SetTabWidget(DocumentTabWidget *tab)
{
m_tab = tab;
SetTabName(m_tabname);
@ -57,17 +57,17 @@ void DocumentTab::SetTabName(const QString& name)
}
/**
* MyTabWidget
* DocumentTabWidget
*/
MyTabWidget::MyTabWidget()
DocumentTabWidget::DocumentTabWidget()
{
setMovable(true);
setTabsClosable(true);
connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(OnCloseTab(int)));
}
void MyTabWidget::SetTabModified(DocumentTab *doc, bool modified)
void DocumentTabWidget::SetTabModified(DocumentTab *doc, bool modified)
{
int index = indexOf(doc->GetWidget());
if(modified)
@ -76,12 +76,12 @@ void MyTabWidget::SetTabModified(DocumentTab *doc, bool modified)
setTabIcon(index, QIcon());
}
void MyTabWidget::SetTabName(DocumentTab *doc, const QString& name)
void DocumentTabWidget::SetTabName(DocumentTab *doc, const QString& name)
{
setTabText(indexOf(doc->GetWidget()), name);
}
bool MyTabWidget::CloseTab(int index)
bool DocumentTabWidget::CloseTab(int index)
{
QWidget *w = this->widget(index);
DocumentTab *doc = dynamic_cast< DocumentTab* >(w);
@ -95,7 +95,7 @@ bool MyTabWidget::CloseTab(int index)
return false;
}
void MyTabWidget::OnCloseTab(int index)
void DocumentTabWidget::OnCloseTab(int index)
{
CloseTab(index);
}
@ -135,7 +135,9 @@ MainWindow::MainWindow(Backend *backend)
about_menu->addAction(about_act);
about_menu->addAction(about_qt_act);
m_tab = new MyTabWidget();
m_tab = new DocumentTabWidget();
m_tab->setTabOpenable(true);
m_tab->setTabOpenMenu(new_submenu);
setCentralWidget(m_tab);
@ -161,8 +163,8 @@ void MainWindow::OnQuit()
void MainWindow::OnAbout()
{
QString soc_desc_ver = QString("%1.%2.%3").arg(MAJOR_VERSION)
.arg(MINOR_VERSION).arg(REVISION_VERSION);
QString soc_desc_ver = QString("%1.%2.%3").arg(soc_desc::MAJOR_VERSION)
.arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION);
QMessageBox::about(this, "About",
"<h1>QEditor</h1>"
"<h2>Version "APP_VERSION"</h2>"
@ -193,7 +195,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::OnLoadDesc()
{
QFileDialog *fd = new QFileDialog(this);
fd->setFilter("XML files (*.xml);;All files (*)");
QStringList filters;
filters << "XML files (*.xml)";
filters << "All files (*)";
fd->setNameFilters(filters);
fd->setFileMode(QFileDialog::ExistingFiles);
fd->setDirectory(Settings::Get()->value("loaddescdir", QDir::currentPath()).toString());
if(fd->exec())

View file

@ -26,8 +26,9 @@
#include <QSettings>
#include "backend.h"
#include "settings.h"
#include "utils.h"
class MyTabWidget;
class DocumentTabWidget;
class DocumentTab
{
@ -35,20 +36,20 @@ public:
DocumentTab() { m_tab = 0; }
virtual bool Quit() = 0;
virtual QWidget *GetWidget() = 0;
void SetTabWidget(MyTabWidget *tab);
void SetTabWidget(DocumentTabWidget *tab);
protected:
void OnModified(bool modified);
void SetTabName(const QString& name);
MyTabWidget *m_tab;
DocumentTabWidget *m_tab;
QString m_tabname;
};
class MyTabWidget : public QTabWidget
class DocumentTabWidget : public YTabWidget
{
Q_OBJECT
public:
MyTabWidget();
DocumentTabWidget();
bool CloseTab(int index);
void SetTabModified(DocumentTab *tab, bool mod);
void SetTabName(DocumentTab *tab, const QString& name);
@ -83,7 +84,7 @@ private slots:
void OnNewRegEdit();
private:
MyTabWidget *m_tab;
DocumentTabWidget *m_tab;
Backend *m_backend;
};

View file

@ -12,7 +12,7 @@ libsocdesc.commands = cd ../lib && make
QMAKE_EXTRA_TARGETS += libsocdesc
PRE_TARGETDEPS += libsocdesc
VERSION = 2.1.0
VERSION = 3.0.0
DEFINES += APP_VERSION=\\\"$$VERSION\\\"

View file

@ -21,36 +21,26 @@
#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");
}
#include <QStandardItemModel>
/**
* SocDisplayPanel
*/
SocDisplayPanel::SocDisplayPanel(QWidget *parent, const SocRef& dev_ref)
:QGroupBox(parent), m_soc(dev_ref)
SocDisplayPanel::SocDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::soc_ref_t& ref)
:QGroupBox(parent), m_soc(ref)
{
Q_UNUSED(io_backend)
QVBoxLayout *right_layout = new QVBoxLayout;
m_name = new QLabel(this);
m_name->setTextFormat(Qt::RichText);
m_name->setText("<h1>" + QString::fromStdString(m_soc.GetSoc().name) + "</h1>");
m_name->setText("<h1>" + QString::fromStdString(m_soc.get()->name) + "</h1>");
m_desc = new QLabel(this);
m_name->setTextFormat(Qt::RichText);
m_desc->setText(QString::fromStdString(m_soc.GetSoc().desc));
m_desc->setText(QString::fromStdString(m_soc.get()->desc));
m_desc->setVisible(m_desc->text().size() != 0);
right_layout->addWidget(m_name, 0);
right_layout->addWidget(m_desc, 0);
@ -71,24 +61,21 @@ QWidget *SocDisplayPanel::GetWidget()
}
/**
* DevDisplayPanel
* NodeDisplayPanel
*/
DevDisplayPanel::DevDisplayPanel(QWidget *parent, const SocDevRef& dev_ref)
:QGroupBox(parent), m_dev(dev_ref), m_reg_font(font())
NodeDisplayPanel::NodeDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::node_inst_t& ref)
:QGroupBox(parent), m_node(ref)
{
BackendHelper helper(io_backend, ref.soc());
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());
QString dev_name = helper.GetPath(ref);
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>");
QLabel *label_addr = new QLabel("<b>" + QString().sprintf("0x%03x", ref.addr()) + "</b>");
label_addr->setTextFormat(Qt::RichText);
QHBoxLayout *top_layout = new QHBoxLayout;
@ -99,27 +86,38 @@ DevDisplayPanel::DevDisplayPanel(QWidget *parent, const SocDevRef& dev_ref)
m_name = new QLabel(this);
m_name->setTextFormat(Qt::RichText);
m_name->setText("<h1>" + QString::fromStdString(m_dev.GetDev().long_name) + "</h1>");
/* if instance has a title, it overrides node title.*/
std::string title = ref.get()->title;
if(title.empty())
title = ref.node().get()->title;
m_name->setText("<h1>" + QString::fromStdString(title) + "</h1>");
m_desc = new QLabel(this);
m_name->setTextFormat(Qt::RichText);
m_desc->setText(QString::fromStdString(m_dev.GetDev().desc));
/* put description from the node and from the instance */
m_node_desc = new QLabel(this);
m_node_desc->setTextFormat(Qt::RichText);
m_node_desc->setText(QString::fromStdString(ref.node().get()->desc));
m_node_desc->setVisible(m_node_desc->text().size() != 0);
m_inst_desc = new QLabel(this);
m_inst_desc->setTextFormat(Qt::RichText);
m_inst_desc->setText(QString::fromStdString(ref.get()->desc));
m_inst_desc->setVisible(m_inst_desc->text().size() != 0);
right_layout->addWidget(m_name, 0);
right_layout->addLayout(top_layout, 0);
right_layout->addWidget(m_desc, 0);
right_layout->addWidget(m_node_desc, 0);
right_layout->addWidget(m_inst_desc, 0);
right_layout->addStretch(1);
setTitle("Device Description");
setLayout(right_layout);
}
void DevDisplayPanel::AllowWrite(bool en)
void NodeDisplayPanel::AllowWrite(bool en)
{
Q_UNUSED(en);
}
QWidget *DevDisplayPanel::GetWidget()
QWidget *NodeDisplayPanel::GetWidget()
{
return this;
}
@ -128,34 +126,29 @@ QWidget *DevDisplayPanel::GetWidget()
* 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())
RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::node_inst_t& ref)
:QGroupBox(parent), m_io_backend(io_backend), m_node(ref), m_reg_font(font())
{
bool read_only = m_io_backend->IsReadOnly();
BackendHelper helper(m_io_backend, ref.soc());
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());
QString reg_name = helper.GetPath(ref);
QStringList names;
QVector< soc_addr_t > addresses;
names.append(reg_name);
addresses.append(reg_addr.addr);
if(reg.flags & REG_HAS_SCT)
addresses.append(ref.addr());
std::vector< soc_desc::variant_ref_t > variants = ref.node().reg().variants();
for(size_t i = 0; i < variants.size(); i++)
{
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);
names.append(reg_name + "/" + QString::fromStdString(variants[i].get()->type));
addresses.append(ref.addr() + variants[i].get()->offset);
}
QString str;
@ -188,7 +181,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
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->EnableSCT(!!(reg.flags & REG_HAS_SCT));
m_raw_val_edit->GetLineEdit()->setFont(m_reg_font);
QHBoxLayout *raw_val_layout = new QHBoxLayout;
raw_val_layout->addStretch();
@ -198,9 +191,13 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
m_value_table = new GrowingTableView();
m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
m_value_model->SetRegister(m_reg.GetReg());
m_value_model->SetRegister(*m_node.node().reg().get());
m_value_model->SetReadOnly(read_only);
m_value_table->setModel(m_value_model);
RegFieldProxyModel *proxy_model = new RegFieldProxyModel(this);
proxy_model->setSourceModel(m_value_model);
m_value_table->setModel(proxy_model);
m_value_table->setSortingEnabled(true);
m_value_table->sortByColumn(0, Qt::DescendingOrder);
m_value_table->verticalHeader()->setVisible(false);
m_value_table->resizeColumnsToContents();
m_value_table->horizontalHeader()->setStretchLastSection(true);
@ -217,17 +214,36 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_value_table->setItemDelegate(m_table_delegate);
m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
m_sexy_display2 = new Unscroll<YRegDisplay>(this);
m_sexy_display2->setFont(m_reg_font);
m_sexy_display2->setModel(m_value_model);
m_sexy_display2->setWidth(m_node.node().reg().get()->width);
m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_name = new QLabel(this);
m_name->setTextFormat(Qt::RichText);
m_name->setText("<h1>" + QString::fromStdString(ref.node().get()->title) + "</h1>");
/* put description from the node, from the instance and register */
m_node_desc = new QLabel(this);
m_node_desc->setTextFormat(Qt::RichText);
m_node_desc->setText(QString::fromStdString(ref.node().get()->desc));
m_node_desc->setVisible(m_node_desc->text().size() != 0);
m_inst_desc = new QLabel(this);
m_inst_desc->setTextFormat(Qt::RichText);
m_inst_desc->setText(QString::fromStdString(ref.get()->desc));
m_inst_desc->setVisible(m_inst_desc->text().size() != 0);
m_desc = new QLabel(this);
m_desc->setTextFormat(Qt::RichText);
m_desc->setText(QString::fromStdString(m_reg.GetReg().desc));
m_desc->setText(QString::fromStdString(m_node.node().reg().get()->desc));
m_desc->setVisible(m_desc->text().size() != 0);
right_layout->addWidget(m_name);
right_layout->addWidget(m_desc);
right_layout->addLayout(top_layout);
right_layout->addWidget(m_node_desc);
right_layout->addWidget(m_inst_desc);
right_layout->addWidget(m_desc);
if(raw_val_layout)
right_layout->addLayout(raw_val_layout);
right_layout->addWidget(m_sexy_display2);
@ -252,8 +268,10 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this,
SLOT(OnRawRegValueReturnPressed()));
connect(m_value_table->model(), SIGNAL(OnValueModified(int)), this,
connect(m_value_model, SIGNAL(OnValueModified(int)), this,
SLOT(OnRegValueChanged(int)));
connect(m_sexy_display2, SIGNAL(clicked(const QModelIndex&)), this,
SLOT(OnRegFieldActivated(const QModelIndex&)));
}
RegDisplayPanel::~RegDisplayPanel()
@ -263,12 +281,9 @@ RegDisplayPanel::~RegDisplayPanel()
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);
BackendHelper helper(m_io_backend, m_node.soc());
bool has_value = helper.ReadRegister(m_node, value);
if(has_value)
{
@ -296,7 +311,6 @@ void RegDisplayPanel::AllowWrite(bool en)
m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
m_value_model->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
}
Reload();
}
IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
@ -320,9 +334,8 @@ void RegDisplayPanel::OnRawRegValueReturnPressed()
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);
BackendHelper helper(m_io_backend, m_node.soc());
helper.WriteRegister(m_node, val, mode);
// register write can change all fields
Reload();
}
@ -332,13 +345,17 @@ void RegDisplayPanel::OnRegValueChanged(int index)
QVariant var = m_value_model->GetValue(index);
if(!var.isValid())
return;
BackendHelper helper(m_io_backend, m_reg);
helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
var.value< soc_word_t >(), IoBackend::Write);
BackendHelper helper(m_io_backend, m_node.soc());
helper.WriteRegister(m_node, var.value< soc_word_t >(), IoBackend::Write);
// register write can change all fields
Reload();
}
void RegDisplayPanel::OnRegFieldActivated(const QModelIndex& index)
{
Q_UNUSED(index);
}
QWidget *RegDisplayPanel::GetWidget()
{
return this;

View file

@ -35,19 +35,12 @@
#include "utils.h"
#include "regtab.h"
class RegItemEditorCreator : public QItemEditorCreatorBase
{
public:
RegItemEditorCreator() {}
virtual QWidget *createWidget(QWidget * parent) const;
virtual QByteArray valuePropertyName () const;
};
class SocDisplayPanel : public QGroupBox, public RegTabPanel
{
Q_OBJECT
public:
SocDisplayPanel(QWidget *parent, const SocRef& reg);
SocDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::soc_ref_t& reg);
void Reload();
void AllowWrite(bool en);
QWidget *GetWidget();
@ -55,16 +48,17 @@ public:
protected:
const SocRef& m_soc;
soc_desc::soc_ref_t m_soc;
QLabel *m_name;
QLabel *m_desc;
};
class DevDisplayPanel : public QGroupBox, public RegTabPanel
class NodeDisplayPanel : public QGroupBox, public RegTabPanel
{
Q_OBJECT
public:
DevDisplayPanel(QWidget *parent, const SocDevRef& reg);
NodeDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::node_inst_t& reg);
void Reload();
void AllowWrite(bool en);
QWidget *GetWidget();
@ -72,17 +66,18 @@ public:
protected:
const SocDevRef& m_dev;
QFont m_reg_font;
soc_desc::node_inst_t m_node;
QLabel *m_name;
QLabel *m_desc;
QLabel *m_node_desc;
QLabel *m_inst_desc;
};
class RegDisplayPanel : public QGroupBox, public RegTabPanel
{
Q_OBJECT
public:
RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg);
RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
const soc_desc::node_inst_t& reg);
~RegDisplayPanel();
void AllowWrite(bool en);
void Reload();
@ -102,17 +97,19 @@ protected:
};
IoBackend *m_io_backend;
const SocRegRef& m_reg;
soc_desc::node_inst_t m_node;
bool m_allow_write;
RegLineEdit *m_raw_val_edit;
Unscroll< RegSexyDisplay2 > *m_sexy_display2;
Unscroll< YRegDisplay > *m_sexy_display2;
GrowingTableView *m_value_table;
RegFieldTableModel *m_value_model;
QStyledItemDelegate *m_table_delegate;
QItemEditorFactory *m_table_edit_factory;
RegItemEditorCreator *m_regedit_creator;
QLabel *m_raw_val_name;
QFont m_reg_font;
QLabel *m_name;
QLabel *m_node_desc;
QLabel *m_inst_desc;
QLabel *m_desc;
QWidget *m_viewport;
QScrollArea *m_scroll;
@ -120,6 +117,7 @@ protected:
private slots:
void OnRawRegValueReturnPressed();
void OnRegValueChanged(int index);
void OnRegFieldActivated(const QModelIndex& index);
};
#endif /* REGDISPLAYPANEL_H */

File diff suppressed because it is too large Load diff

View file

@ -38,6 +38,8 @@
#include <QButtonGroup>
#include <QDebug>
#include <QScrollArea>
#include <QSpinBox>
#include <QFormLayout>
#include "backend.h"
#include "settings.h"
#include "mainwindow.h"
@ -48,7 +50,7 @@ class AbstractRegEditPanel
public:
AbstractRegEditPanel() {}
virtual ~AbstractRegEditPanel() {}
virtual void OnModified(bool mod) = 0;
virtual void OnModified() = 0;
};
class EmptyEditPanel : public QWidget, public AbstractRegEditPanel
@ -58,7 +60,7 @@ public:
EmptyEditPanel(QWidget *parent);
signals:
void OnModified(bool mod);
void OnModified();
protected:
};
@ -67,178 +69,167 @@ class SocEditPanel : public QWidget, public AbstractRegEditPanel
{
Q_OBJECT
public:
SocEditPanel(SocRef ref, QWidget *parent = 0);
SocEditPanel(const soc_desc::soc_ref_t& ref, QWidget *parent = 0);
signals:
void OnModified(bool mod);
void OnModified();
protected slots:
void OnTextEdited();
void OnNameEdited(const QString& text);
void OnTitleEdited(const QString& text);
void OnVersionEdited(const QString& text);
void OnIsaEdited(const QString& text);
void OnAuthorActivated(QTableWidgetItem *);
void OnAuthorChanged(QTableWidgetItem *);
protected:
SocRef m_ref;
QGroupBox *m_name_group;
QLineEdit *m_name_edit;
QGroupBox *m_desc_group;
soc_desc::soc_ref_t m_ref;
QTableWidget *m_authors_list;
MyTextEditor *m_desc_edit;
};
class DevEditPanel : public QWidget, public AbstractRegEditPanel
class NodeInstanceEditPanel : public QWidget
{
Q_OBJECT
public:
DevEditPanel(SocDevRef ref, QWidget *parent = 0);
NodeInstanceEditPanel(const soc_desc::node_ref_t& ref, soc_id_t inst_id,
QWidget *parent = 0);
soc_id_t GetId();
soc_desc::instance_t& GetInstance();
signals:
void OnModified(bool mod);
void OnModified();
protected slots:
void OnInstActivated(int row, int column);
void OnInstChanged(int row, int column);
void OnNameEdited(const QString& text);
void OnLongNameEdited(const QString& text);
void OnVersionEdited(const QString& text);
void OnDescEdited();
void OnTitleEdited(const QString& text);
void OnDescEdited(const QString& text);
void OnTypeChanged(int index);
void OnAddrChanged(uint addr);
void OnBaseChanged(uint base);
void OnStrideChanged(uint stride);
void OnFirstChanged(int first);
void OnCountChanged(int count);
void OnFormulaChanged(const QString& formula);
void OnVariableChanged(const QString& variable);
void OnAddressActivated(QTableWidgetItem *);
void OnAddressChanged(QTableWidgetItem *);
protected:
void FillRow(int row, const soc_dev_addr_t& addr);
void CreateNewRow(int row);
void UpdateType(int type);
enum
{
DevInstDeleteType = QTableWidgetItem::UserType,
DevInstNewType
};
soc_desc::node_ref_t m_ref;
soc_id_t m_id;
QComboBox *m_type_combo;
QWidget *m_single_group;
QWidget *m_range_group;
QWidget *m_formula_group;
QWidget *m_stride_group;
QWidget *m_list_group;
QStyledItemDelegate *m_table_delegate;
SocFieldEditorCreator *m_table_edit_factory;
};
enum
{
DevInstIconColumn = 0,
DevInstNameColumn = 1,
DevInstAddrColumn = 2,
};
class NodeEditPanel : public QWidget, public AbstractRegEditPanel
{
Q_OBJECT
public:
NodeEditPanel(const soc_desc::node_ref_t& ref, QWidget *parent = 0);
SocDevRef m_ref;
QGroupBox *m_name_group;
QLineEdit *m_name_edit;
QGroupBox *m_long_name_group;
QLineEdit *m_long_name_edit;
QGroupBox *m_version_group;
QLineEdit *m_version_edit;
QGroupBox *m_instances_group;
QTableWidget *m_instances_table;
QGroupBox *m_desc_group;
signals:
void OnModified();
protected slots:
void OnNameEdited(const QString& text);
void OnTitleEdited(const QString& text);
void OnDescEdited();
void OnInstRemove(int index);
void OnInstCreate();
void OnInstModified();
protected:
soc_desc::instance_t *GetInstanceById(soc_id_t id);
soc_desc::instance_t *GetInstanceByRow(int row);
QString GuessName();
soc_desc::node_ref_t m_ref;
MyTextEditor *m_desc_edit;
YTabWidget *m_instances_tab;
};
class RegFieldEditPanel : public QWidget
{
Q_OBJECT
public:
RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent = 0);
soc_desc::field_ref_t GetField();
void UpdateWidth();
signals:
void OnModified();
protected slots:
void OnFieldNameChanged(const QString& name);
void OnFieldRangeChanged(const QString& range);
void OnFieldDescChanged(const QString& name);
void OnFieldValueActivated(QTableWidgetItem *item);
void OnFieldValueChanged(QTableWidgetItem *item);
protected:
soc_desc::field_ref_t m_ref;
QLineEdit *m_name_edit;
QLineEdit *m_range_edit;
SocBitRangeValidator *m_range_validator;
MyTextEditor *m_desc_edit;
QTableWidget *m_enum_table;
SocFieldItemDelegate *m_enum_delegate;
SocFieldEditorCreator *m_enum_editor;
};
class RegEditPanel : public QWidget, public AbstractRegEditPanel
{
Q_OBJECT
public:
RegEditPanel(SocRegRef ref, QWidget *parent = 0);
RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent = 0);
signals:
void OnModified(bool mod);
void OnModified();
protected slots:
void OnInstActivated(int row, int column);
void OnInstChanged(int row, int column);
void OnNameEdited(const QString& text);
void OnRegFieldActivated(const QModelIndex& index);
void OnRegDisplayContextMenu(QPoint point);
void OnRegFieldDelete();
void OnRegFieldNew();
void OnWidthChanged(int size);
void OnFieldModified();
void OnDescEdited();
void OnSctEdited(int state);
void OnFormulaChanged(int index);
void OnFormulaStringChanged(const QString& text);
void OnFormulaGenerate(bool checked);
void OnVariantActivated(QTableWidgetItem *item);
void OnVariantValueChanged(QTableWidgetItem *item);
void OnFieldRemove(int index);
void OnFieldCreate();
protected:
void CreateNewAddrRow(int row);
void FillRow(int row, const soc_reg_addr_t& addr);
void UpdateFormula();
void UpdateWarning(int row);
void DoModify();
int FindFreeBit(int preferred);
int IndexById(soc_id_t id); // tab index
void UpdateWidthRestrictions();
enum
{
RegInstDeleteType = QTableWidgetItem::UserType,
RegInstNewType
};
enum
{
RegInstIconColumn = 0,
RegInstNameColumn,
RegInstAddrColumn,
RegInstNrColumns,
};
SocRegRef m_ref;
QGroupBox *m_name_group;
QLineEdit *m_name_edit;
QGroupBox *m_instances_group;
QTableWidget *m_instances_table;
QGroupBox *m_desc_group;
QGroupBox *m_flags_group;
QCheckBox *m_sct_check;
MyTextEditor *m_desc_edit;
soc_desc::register_ref_t m_ref;
QFont m_reg_font;
QGroupBox *m_formula_group;
QButtonGroup *m_formula_radio_group;
QLabel *m_formula_type_label;
QComboBox *m_formula_combo;
QLineEdit *m_formula_string_edit;
QPushButton *m_formula_string_gen;
Unscroll< RegSexyDisplay2 > *m_sexy_display2;
MyTextEditor *m_desc_edit;
QGroupBox *m_field_group;
QTableView *m_value_table;
Unscroll< YRegDisplay > *m_sexy_display2;
RegFieldTableModel *m_value_model;
QStyledItemDelegate *m_table_delegate;
};
class FieldEditPanel : public QWidget, public AbstractRegEditPanel
{
Q_OBJECT
public:
FieldEditPanel(SocFieldRef ref, QWidget *parent = 0);
signals:
void OnModified(bool mod);
protected slots:
void OnDescEdited();
void OnNameEdited(const QString& text);
void OnBitRangeEdited(const QString& string);
void OnValueActivated(int row, int column);
void OnValueChanged(int row, int column);
protected:
void CreateNewRow(int row);
void FillRow(int row, const soc_reg_field_value_t& val);
void UpdateWarning(int row);
void UpdateDelegates();
enum
{
FieldValueDeleteType = QTableWidgetItem::UserType,
FieldValueNewType,
};
enum
{
FieldValueIconColumn = 0,
FieldValueNameColumn,
FieldValueValueColumn,
FieldValueDescColumn,
FieldValueNrColumns,
};
SocFieldRef m_ref;
QGroupBox *m_name_group;
QLineEdit *m_name_edit;
QGroupBox *m_bitrange_group;
QLineEdit *m_bitrange_edit;
QGroupBox *m_desc_group;
MyTextEditor *m_desc_edit;
QGroupBox *m_value_group;
QTableWidget *m_value_table;
YTabWidget *m_fields_tab;
QTabWidget *m_view_tab;
QTableWidget *m_variant_table;
QAction *m_new_action;
QAction *m_delete_action;
QPoint m_menu_point;
SocFieldItemDelegate *m_variant_delegate;
SocFieldEditorCreator *m_variant_editor;
QButtonGroup *m_reg_size_group;
};
class RegEdit : public QWidget, public DocumentTab
@ -252,43 +243,50 @@ public:
protected slots:
void OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void OnSocItemActivated(QTreeWidgetItem *current, int column);
void OnOpen();
void OnSave();
void OnSaveAs();
void OnSocModified(bool modified);
void OnSocModified();
void OnNew();
void OnSocItemDelete();
void OnSocItemNew();
void OnSocItemCreate();
void OnSocTreeContextMenu(QPoint point);
protected:
void LoadSocFile(const QString& filename);
void UpdateSocFile();
void FillSocTree();
void FillSocTreeItem(QTreeWidgetItem *_item);
void FillDevTreeItem(QTreeWidgetItem *_item);
void FillRegTreeItem(QTreeWidgetItem *_item);
void FillNodeTreeItem(QTreeWidgetItem *item);
void SetPanel(QWidget *panel);
void DisplaySoc(SocRef ref);
void DisplayDev(SocDevRef ref);
void DisplayReg(SocRegRef ref);
void DisplayField(SocFieldRef ref);
void DisplaySoc(const soc_desc::soc_ref_t& ref);
void DisplayNode(const soc_desc::node_ref_t& ref);
void DisplayReg(const soc_desc::register_ref_t& ref);
bool CloseSoc();
bool SaveSoc();
bool SaveSocAs();
bool SaveSocFile(const QString& filename);
bool GetFilename(QString& filename, bool save);
void SetModified(bool add, bool mod);
void FixupEmptyItem(QTreeWidgetItem *item);
void FixupItem(QTreeWidgetItem *item);
QIcon GetIconFromType(int type);
void MakeItalic(QTreeWidgetItem *item, bool it);
void AddDevice(QTreeWidgetItem *item);
void AddRegister(QTreeWidgetItem *_item);
void UpdateName(QTreeWidgetItem *current);
void AddField(QTreeWidgetItem *_item);
void CreateNewDeviceItem(QTreeWidgetItem *parent);
void CreateNewNodeItem(QTreeWidgetItem *parent);
void CreateNewRegisterItem(QTreeWidgetItem *parent);
void CreateNewFieldItem(QTreeWidgetItem *parent);
void UpdateTabName();
bool ValidateName(const QString& name);
int SetMessage(MessageWidget::MessageType type, const QString& msg);
void HideMessage(int id);
QAction *m_delete_action;
QAction *m_new_action;
QAction *m_create_action;
QTreeWidgetItem *m_action_item;
QGroupBox *m_file_group;
QToolButton *m_file_open;
QToolButton *m_file_save;
@ -299,6 +297,10 @@ protected:
bool m_modified;
SocFile m_cur_socfile;
QWidget *m_right_panel;
MessageWidget *m_msg;
QVBoxLayout *m_right_panel_layout;
int m_msg_welcome_id;
int m_msg_name_error_id;
};
#endif /* REGEDIT_H */

View file

@ -35,42 +35,7 @@ namespace
enum
{
RegTreeDevType = QTreeWidgetItem::UserType,
RegTreeRegType,
RegTreeSocType
};
class SocTreeItem : public QTreeWidgetItem
{
public:
SocTreeItem(const QString& string, const SocRef& ref)
:QTreeWidgetItem(QStringList(string), RegTreeSocType), m_ref(ref) {}
const SocRef& GetRef() { return m_ref; }
private:
SocRef m_ref;
};
class DevTreeItem : public QTreeWidgetItem
{
public:
DevTreeItem(const QString& string, const SocDevRef& ref)
:QTreeWidgetItem(QStringList(string), RegTreeDevType), m_ref(ref) {}
const SocDevRef& GetRef() { return m_ref; }
private:
SocDevRef m_ref;
};
class RegTreeItem : public QTreeWidgetItem
{
public:
RegTreeItem(const QString& string, const SocRegRef& ref)
:QTreeWidgetItem(QStringList(string), RegTreeRegType), m_ref(ref) {}
const SocRegRef& GetRef() { return m_ref; }
private:
SocRegRef m_ref;
NodeInstRole = Qt::UserRole,
};
}
@ -165,7 +130,8 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
connect(m_soc_selector, SIGNAL(currentIndexChanged(int)),
this, SLOT(OnSocChanged(int)));
connect(m_backend, SIGNAL(OnSocListChanged()), this, SLOT(OnSocListChanged()));
connect(m_backend, SIGNAL(OnSocAdded(const SocFileRef&)), this,
SLOT(OnSocAdded(const SocFileRef&)));
connect(m_reg_tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
this, SLOT(OnRegItemClicked(QTreeWidgetItem*, int)));
connect(m_data_soc_label, SIGNAL(linkActivated(const QString&)), this,
@ -183,7 +149,9 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
"You can browse the registers. Select a data source to analyse the values.");
m_msg_error_id = 0;
OnSocListChanged();
QList< SocFileRef > socs = m_backend->GetSocFileList();
for(int i = 0; i < socs.size(); i++)
OnSocAdded(socs[i]);
SetDataSocName("");
UpdateTabName();
}
@ -286,21 +254,7 @@ void RegTab::OnRegItemClicked(QTreeWidgetItem *current, int col)
Q_UNUSED(col);
if(current == 0)
return;
if(current->type() == RegTreeSocType)
{
SocTreeItem *item = dynamic_cast< SocTreeItem * >(current);
DisplaySoc(item->GetRef());
}
if(current->type() == RegTreeRegType)
{
RegTreeItem *item = dynamic_cast< RegTreeItem * >(current);
DisplayRegister(item->GetRef());
}
else if(current->type() == RegTreeDevType)
{
DevTreeItem *item = dynamic_cast< DevTreeItem * >(current);
DisplayDevice(item->GetRef());
}
DisplayNode(NodeInst(current));
}
void RegTab::OnAnalyserClicked(QListWidgetItem *current)
@ -311,19 +265,14 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current)
SetPanel(ana->Create(m_cur_soc, m_io_backend));
}
void RegTab::DisplayRegister(const SocRegRef& ref)
void RegTab::DisplayNode(const soc_desc::node_inst_t& ref)
{
SetPanel(new RegDisplayPanel(this, m_io_backend, ref));
}
void RegTab::DisplayDevice(const SocDevRef& ref)
{
SetPanel(new DevDisplayPanel(this, ref));
}
void RegTab::DisplaySoc(const SocRef& ref)
{
SetPanel(new SocDisplayPanel(this, ref));
if(ref.node().is_root())
SetPanel(new SocDisplayPanel(this, m_io_backend, ref.soc()));
else if(ref.node().reg().valid())
SetPanel(new RegDisplayPanel(this, m_io_backend, ref));
else
SetPanel(new NodeDisplayPanel(this, m_io_backend, ref));
}
int RegTab::SetMessage(MessageWidget::MessageType type, const QString& msg)
@ -344,56 +293,45 @@ void RegTab::SetPanel(RegTabPanel *panel)
m_right_panel->addWidget(m_right_content->GetWidget(), 1);
}
void RegTab::OnSocListChanged()
void RegTab::OnSocAdded(const SocFileRef& ref)
{
m_soc_selector->clear();
QList< SocRef > socs = m_backend->GetSocList();
for(int i = 0; i < socs.size(); i++)
{
QVariant v;
v.setValue(socs[i]);
m_soc_selector->addItem(QString::fromStdString(socs[i].GetSoc().name), v);
}
soc_desc::soc_ref_t soc = ref.GetSocFile()->GetSocRef();
QVariant v;
v.setValue(soc);
m_soc_selector->addItem(QString::fromStdString(soc.get()->name), v);
}
void RegTab::FillDevSubTree(QTreeWidgetItem *_item)
QTreeWidgetItem *RegTab::MakeNode(const soc_desc::node_inst_t& inst, const QString& s)
{
DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item);
const soc_dev_t& dev = item->GetRef().GetDev();
for(size_t i = 0; i < dev.reg.size(); i++)
{
const soc_reg_t& reg = dev.reg[i];
for(size_t j = 0; j < reg.addr.size(); j++)
{
RegTreeItem *reg_item = new RegTreeItem(reg.addr[j].name.c_str(),
SocRegRef(item->GetRef(), i, j));
item->addChild(reg_item);
}
}
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(s));
item->setData(0, NodeInstRole, QVariant::fromValue(inst));
return item;
}
void RegTab::FillSocSubTree(QTreeWidgetItem *_item)
soc_desc::node_inst_t RegTab::NodeInst(QTreeWidgetItem *item)
{
SocTreeItem *item = dynamic_cast< SocTreeItem* >(_item);
const soc_t& soc = item->GetRef().GetSoc();
for(size_t i = 0; i < soc.dev.size(); i++)
return item->data(0, NodeInstRole).value< soc_desc::node_inst_t >();
}
void RegTab::FillSubTree(QTreeWidgetItem *item)
{
std::vector< soc_desc::node_inst_t > list = NodeInst(item).children();
for(size_t i = 0; i < list.size(); i++)
{
const soc_dev_t& dev = soc.dev[i];
for(size_t j = 0; j < dev.addr.size(); j++)
{
DevTreeItem *dev_item = new DevTreeItem(dev.addr[j].name.c_str(),
SocDevRef(m_cur_soc, i, j));
FillDevSubTree(dev_item);
item->addChild(dev_item);
}
QString name = QString::fromStdString(list[i].name());
if(list[i].is_indexed())
name = QString("%1[%2]").arg(name).arg(list[i].index());
QTreeWidgetItem *child = MakeNode(list[i], name);
FillSubTree(child);
item->addChild(child);
}
}
void RegTab::FillRegTree()
{
SocTreeItem *soc_item = new SocTreeItem(m_cur_soc.GetSoc().name.c_str(),
m_cur_soc);
FillSocSubTree(soc_item);
QTreeWidgetItem *soc_item = MakeNode(m_cur_soc.root_inst(),
QString::fromStdString(m_cur_soc.get()->name));
FillSubTree(soc_item);
m_reg_tree->addTopLevelItem(soc_item);
m_reg_tree->expandItem(soc_item);
}
@ -401,7 +339,8 @@ void RegTab::FillRegTree()
void RegTab::FillAnalyserList()
{
m_analysers_list->clear();
m_analysers_list->addItems(AnalyserFactory::GetAnalysersForSoc(m_cur_soc.GetSoc().name.c_str()));
m_analysers_list->addItems(AnalyserFactory::GetAnalysersForSoc(
QString::fromStdString(m_cur_soc.get()->name)));
}
void RegTab::OnSocChanged(int index)
@ -409,7 +348,7 @@ void RegTab::OnSocChanged(int index)
if(index == -1)
return;
m_reg_tree->clear();
m_cur_soc = m_soc_selector->itemData(index).value< SocRef >();
m_cur_soc = m_soc_selector->itemData(index).value< soc_desc::soc_ref_t >();
FillRegTree();
FillAnalyserList();
}
@ -426,7 +365,10 @@ void RegTab::OnDumpRegs(bool c)
Q_UNUSED(c);
QFileDialog *fd = new QFileDialog(this);
fd->setAcceptMode(QFileDialog::AcceptSave);
fd->setFilter("Textual files (*.txt);;All files (*)");
QStringList filters;
filters << "Textual files (*.txt)";
filters << "All files (*)";
fd->setNameFilters(filters);
fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString());
if(!fd->exec())
return;

View file

@ -66,14 +66,13 @@ public:
virtual QWidget *GetWidget();
protected:
void FillDevSubTree(QTreeWidgetItem *item);
void FillSocSubTree(QTreeWidgetItem *item);
QTreeWidgetItem *MakeNode(const soc_desc::node_inst_t& inst, const QString& s);
soc_desc::node_inst_t NodeInst(QTreeWidgetItem *item);
void FillSubTree(QTreeWidgetItem *item);
void FillRegTree();
void FillAnalyserList();
void UpdateSocList();
void DisplayRegister(const SocRegRef& ref);
void DisplayDevice(const SocDevRef& ref);
void DisplaySoc(const SocRef& ref);
void DisplayNode(const soc_desc::node_inst_t& ref);
void SetDataSocName(const QString& socname);
void SetPanel(RegTabPanel *panel);
void UpdateSocFilename();
@ -85,7 +84,7 @@ protected:
BackendSelector *m_backend_selector;
Backend *m_backend;
QTreeWidget *m_reg_tree;
SocRef m_cur_soc;
soc_desc::soc_ref_t m_cur_soc;
QVBoxLayout *m_right_panel;
RegTabPanel *m_right_content;
QCheckBox *m_readonly_check;
@ -102,7 +101,7 @@ protected:
private slots:
void SetReadOnlyIndicator();
void OnSocChanged(int index);
void OnSocListChanged();
void OnSocAdded(const SocFileRef& ref);
void OnRegItemClicked(QTreeWidgetItem *clicked, int col);
void OnBackendSelect(IoBackend *backend);
void OnDataChanged();

View file

@ -19,13 +19,44 @@
*
****************************************************************************/
#include "std_analysers.h"
#include <QDebug>
/**
* AnalyserEx
*/
AnalyserEx::AnalyserEx(const soc_desc::soc_ref_t& soc, IoBackend *backend)
:Analyser(soc, backend), m_helper(backend, soc)
{
}
bool AnalyserEx::ReadRegister(const QString& path, soc_word_t& val)
{
return m_helper.ReadRegister(m_helper.ParsePath(path), val);
}
bool AnalyserEx::ReadRegisterOld(const QString& dev, const QString& reg, soc_word_t& val)
{
return ReadRegister(dev + "." + reg, val);
}
bool AnalyserEx::ReadField(const QString& path, const QString& field, soc_word_t& val)
{
return m_helper.ReadRegisterField(m_helper.ParsePath(path), field, val);
}
bool AnalyserEx::ReadFieldOld(const QString& dev, const QString& reg,
const QString& field, soc_word_t& val)
{
return ReadField(dev + "." + reg, field, val);
}
/**
* Clock analyser
*/
ClockAnalyser::ClockAnalyser(const SocRef& soc, IoBackend *backend)
:Analyser(soc, backend)
ClockAnalyser::ClockAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend)
:AnalyserEx(soc, backend)
{
m_group = new QGroupBox("Clock Analyser");
QVBoxLayout *layout = new QVBoxLayout;
@ -75,7 +106,8 @@ QString ClockAnalyser::GetFreq(unsigned freq)
return QString().sprintf("%d Hz", freq);
}
QTreeWidgetItem *ClockAnalyser::AddClock(QTreeWidgetItem *parent, const QString& name, int freq, int mul, int div)
QTreeWidgetItem *ClockAnalyser::AddClock(QTreeWidgetItem *parent, const QString& name,
int freq, int mul, int div)
{
if(freq == FROM_PARENT)
{
@ -102,9 +134,9 @@ int ClockAnalyser::GetClockFreq(QTreeWidgetItem *item)
void ClockAnalyser::FillTree()
{
m_tree_widget->clear();
if(m_soc.GetSoc().name == "imx233") FillTreeIMX233();
else if(m_soc.GetSoc().name == "rk27xx") FillTreeRK27XX();
else if(m_soc.GetSoc().name == "atj213x") FillTreeATJ213X();
if(m_soc.get()->name == "imx233") FillTreeIMX233();
else if(m_soc.get()->name == "rk27xx") FillTreeRK27XX();
else if(m_soc.get()->name == "atj213x") FillTreeATJ213X();
m_tree_widget->expandAll();
m_tree_widget->resizeColumnToContents(0);
}
@ -113,17 +145,15 @@ void ClockAnalyser::FillTreeATJ213X()
{
soc_word_t pllbypass, pllclk, en, coreclks, tmp0, tmp1, tmp2, tmp3;
BackendHelper helper(m_io_backend, m_soc);
// system oscillators 32.768k and 24M
QTreeWidgetItem *losc_clk = AddClock(0, "losc clk", 32768);
QTreeWidgetItem *hosc_clk = AddClock(0, "hosc clk", 24000000);
// core pll
QTreeWidgetItem *corepll = 0;
if (helper.ReadRegisterField("CMU", "COREPLL", "CPEN", en) &&
helper.ReadRegisterField("CMU", "COREPLL", "CPBY", pllbypass) &&
helper.ReadRegisterField("CMU", "COREPLL", "CPCK", pllclk))
if(ReadFieldOld("CMU", "COREPLL", "CPEN", en) &&
ReadFieldOld("CMU", "COREPLL", "CPBY", pllbypass) &&
ReadFieldOld("CMU", "COREPLL", "CPCK", pllclk))
{
corepll = AddClock(hosc_clk, "core pll", en ? FROM_PARENT : DISABLED,
pllbypass ? 1 : pllclk, pllbypass ? 1 : 4);
@ -135,8 +165,8 @@ void ClockAnalyser::FillTreeATJ213X()
// dsp pll
QTreeWidgetItem *dsppll = 0;
if (helper.ReadRegisterField("CMU", "DSPPLL", "DPEN", en) &&
helper.ReadRegisterField("CMU", "DSPPLL", "DPCK", pllclk))
if(ReadFieldOld("CMU", "DSPPLL", "DPEN", en) &&
ReadFieldOld("CMU", "DSPPLL", "DPCK", pllclk))
{
dsppll = AddClock(hosc_clk, "dsp pll", en ? FROM_PARENT : DISABLED,
pllbypass ? 1 : pllclk, pllbypass ? 1 : 4);
@ -149,11 +179,11 @@ void ClockAnalyser::FillTreeATJ213X()
// audio pll
QTreeWidgetItem *adcpll = 0;
QTreeWidgetItem *dacpll = 0;
if (helper.ReadRegisterField("CMU", "AUDIOPLL", "APEN", en) &&
helper.ReadRegisterField("CMU", "AUDIOPLL", "ADCCLK", tmp0) &&
helper.ReadRegisterField("CMU", "AUDIOPLL", "DACCLK", tmp1))
if(ReadFieldOld("CMU", "AUDIOPLL", "APEN", en) &&
ReadFieldOld("CMU", "AUDIOPLL", "ADCCLK", tmp0) &&
ReadFieldOld("CMU", "AUDIOPLL", "DACCLK", tmp1))
{
if (en)
if(en)
{
adcpll = AddClock(hosc_clk, "audio adc pll", tmp0 ? 22579200 : 24576000);
dacpll = AddClock(hosc_clk, "audio dac pll", tmp1 ? 22579200 : 24576000);
@ -173,8 +203,8 @@ void ClockAnalyser::FillTreeATJ213X()
// audio clocks
QTreeWidgetItem *adcclk = 0;
QTreeWidgetItem *dacclk = 0;
if (helper.ReadRegisterField("CMU", "AUDIOPLL", "ADCCLK", tmp0) &&
helper.ReadRegisterField("CMU", "AUDIOPLL", "DACCLK", tmp1))
if(ReadFieldOld("CMU", "AUDIOPLL", "ADCCLK", tmp0) &&
ReadFieldOld("CMU", "AUDIOPLL", "DACCLK", tmp1))
{
adcclk = AddClock(adcpll, "audio adc clk", FROM_PARENT, 1, tmp0+1);
dacclk = AddClock(dacpll, "audio dac clk", FROM_PARENT, 1, tmp1+1);
@ -187,14 +217,14 @@ void ClockAnalyser::FillTreeATJ213X()
// cpu clock
QTreeWidgetItem *cpuclk = 0;
if (helper.ReadRegisterField("CMU", "BUSCLK", "CORECLKS", coreclks) &&
helper.ReadRegisterField("CMU", "BUSCLK", "CCLKDIV", tmp0))
if(ReadFieldOld("CMU", "BUSCLK", "CORECLKS", coreclks) &&
ReadFieldOld("CMU", "BUSCLK", "CCLKDIV", tmp0))
{
if (coreclks == 0)
if(coreclks == 0)
cpuclk = AddClock(losc_clk, "cpu clk", FROM_PARENT, 1, tmp0+1);
else if (coreclks == 1)
else if(coreclks == 1)
cpuclk = AddClock(hosc_clk, "cpu clk", FROM_PARENT, 1, tmp0+1);
else if (coreclks == 2)
else if(coreclks == 2)
cpuclk = AddClock(corepll, "cpu clk", FROM_PARENT, 1, tmp0+1);
else
cpuclk = AddClock(corepll, "cpu clk", INVALID);
@ -206,24 +236,24 @@ void ClockAnalyser::FillTreeATJ213X()
// system clock
QTreeWidgetItem *sysclk = 0;
if (helper.ReadRegisterField("CMU", "BUSCLK", "SCLKDIV", tmp0))
if(ReadFieldOld("CMU", "BUSCLK", "SCLKDIV", tmp0))
sysclk = AddClock(cpuclk, "system clk", FROM_PARENT, 1, tmp0+1);
else
sysclk = AddClock(cpuclk, "system clk", INVALID);
// peripherial clk
QTreeWidgetItem *pclk = 0;
if (helper.ReadRegisterField("CMU", "BUSCLK", "PCLKDIV", tmp0))
if(ReadFieldOld("CMU", "BUSCLK", "PCLKDIV", tmp0))
pclk = AddClock(sysclk, "peripherial clk", FROM_PARENT, 1, tmp0 ? tmp0+1 : 2);
else
pclk = AddClock(sysclk, "peripherial clk", INVALID);
// sdram clk
QTreeWidgetItem *sdrclk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "SDRC", en) &&
helper.ReadRegisterField("CMU", "DEVCLKEN", "SDRM", tmp0) &&
helper.ReadRegisterField("SDR", "EN", "EN", tmp1) &&
helper.ReadRegisterField("CMU", "SDRCLK", "SDRDIV", tmp2))
if(ReadFieldOld("CMU", "DEVCLKEN", "SDRC", en) &&
ReadFieldOld("CMU", "DEVCLKEN", "SDRM", tmp0) &&
ReadFieldOld("SDR", "EN", "EN", tmp1) &&
ReadFieldOld("CMU", "SDRCLK", "SDRDIV", tmp2))
{
en &= tmp0 & tmp1;
sdrclk = AddClock(sysclk, "sdram clk", en ? FROM_PARENT: DISABLED, 1, tmp2+1);
@ -233,18 +263,18 @@ void ClockAnalyser::FillTreeATJ213X()
// nand clk
QTreeWidgetItem *nandclk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "NAND", en) &&
helper.ReadRegisterField("CMU", "NANDCLK", "NANDDIV", tmp0))
if(ReadFieldOld("CMU", "DEVCLKEN", "NAND", en) &&
ReadFieldOld("CMU", "NANDCLK", "NANDDIV", tmp0))
nandclk = AddClock(corepll, "nand clk", en ? FROM_PARENT : DISABLED, 1, tmp0+1);
else
nandclk = AddClock(corepll, "nand clk", INVALID);
// sd clk
QTreeWidgetItem *sdclk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "SD", tmp0) &&
helper.ReadRegisterField("CMU", "SDCLK", "CKEN" , tmp1) &&
helper.ReadRegisterField("CMU", "SDCLK", "D128" , tmp2) &&
helper.ReadRegisterField("CMU", "SDCLK", "SDDIV" , tmp3))
if(ReadFieldOld("CMU", "DEVCLKEN", "SD", tmp0) &&
ReadFieldOld("CMU", "SDCLK", "CKEN" , tmp1) &&
ReadFieldOld("CMU", "SDCLK", "D128" , tmp2) &&
ReadFieldOld("CMU", "SDCLK", "SDDIV" , tmp3))
{
en = tmp0 & tmp1;
sdclk = AddClock(corepll, "sd clk", en ? FROM_PARENT : DISABLED,
@ -255,8 +285,8 @@ void ClockAnalyser::FillTreeATJ213X()
// mha clk
QTreeWidgetItem *mhaclk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "MHA", en) &&
helper.ReadRegisterField("CMU", "MHACLK", "MHADIV", tmp1))
if(ReadFieldOld("CMU", "DEVCLKEN", "MHA", en) &&
ReadFieldOld("CMU", "MHACLK", "MHADIV", tmp1))
mhaclk = AddClock(corepll, "mha clk", en ? FROM_PARENT : DISABLED,
1, tmp1+1);
else
@ -264,8 +294,8 @@ void ClockAnalyser::FillTreeATJ213X()
// mca clk
QTreeWidgetItem *mcaclk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "MCA", en) &&
helper.ReadRegisterField("CMU", "MCACLK", "MCADIV", tmp1))
if(ReadFieldOld("CMU", "DEVCLKEN", "MCA", en) &&
ReadFieldOld("CMU", "MCACLK", "MCADIV", tmp1))
mcaclk = AddClock(corepll, "mca clk", en ? FROM_PARENT : DISABLED,
1, tmp1+1);
else
@ -273,11 +303,11 @@ void ClockAnalyser::FillTreeATJ213X()
// backlight pwm
QTreeWidgetItem *pwmclk = 0;
if (helper.ReadRegisterField("CMU", "FMCLK", "BCKE", en) &&
helper.ReadRegisterField("CMU", "FMCLK", "BCKS", tmp1) &&
helper.ReadRegisterField("CMU", "FMCLK", "BCKCON", tmp2))
if(ReadFieldOld("CMU", "FMCLK", "BCKE", en) &&
ReadFieldOld("CMU", "FMCLK", "BCKS", tmp1) &&
ReadFieldOld("CMU", "FMCLK", "BCKCON", tmp2))
{
if (tmp1)
if(tmp1)
{
// HOSC/8 input clk
pwmclk = AddClock(hosc_clk, "pwm clk", en ? FROM_PARENT : DISABLED,
@ -296,9 +326,9 @@ void ClockAnalyser::FillTreeATJ213X()
// i2c clk
QTreeWidgetItem *i2c1clk = 0;
QTreeWidgetItem *i2c2clk = 0;
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "I2C", en) &&
helper.ReadRegisterField("I2C1", "CTL", "EN", tmp0) &&
helper.ReadRegisterField("I2C1", "CLKDIV", "CLKDIV", tmp1))
if(ReadFieldOld("CMU", "DEVCLKEN", "I2C", en) &&
ReadFieldOld("I2C1", "CTL", "EN", tmp0) &&
ReadFieldOld("I2C1", "CLKDIV", "CLKDIV", tmp1))
{
en &= tmp0;
i2c1clk = AddClock(pclk, "i2c1 clk", en ? FROM_PARENT : DISABLED,
@ -309,16 +339,16 @@ void ClockAnalyser::FillTreeATJ213X()
i2c1clk = AddClock(pclk, "i2c1 clk", INVALID);
}
if (helper.ReadRegisterField("CMU", "DEVCLKEN", "I2C", en) &&
helper.ReadRegisterField("I2C2", "CTL", "EN", tmp0) &&
helper.ReadRegisterField("I2C2", "CLKDIV", "CLKDIV", tmp1))
if(ReadFieldOld("CMU", "DEVCLKEN", "I2C", en) &&
ReadFieldOld("I2C2", "CTL", "EN", tmp0) &&
ReadFieldOld("I2C2", "CLKDIV", "CLKDIV", tmp1))
{
en &= tmp0;
i2c2clk = AddClock(pclk, "i2c2 clk", en ? FROM_PARENT : DISABLED,
1, 16*(tmp1+1));
}
else
{
{
i2c2clk = AddClock(pclk, "i2c2 clk", INVALID);
}
@ -340,17 +370,15 @@ void ClockAnalyser::FillTreeRK27XX()
soc_word_t value, value2, value3, value4;
soc_word_t bypass, clkr, clkf, clkod, pll_off;
BackendHelper helper(m_io_backend, m_soc);
QTreeWidgetItem *xtal_clk = AddClock(0, "xtal clk", 24000000);
// F = (Fref*F)/R/OD = (Fref*F)/R/OD
QTreeWidgetItem *arm_pll = 0;
if (helper.ReadRegisterField("SCU", "PLLCON1", "ARM_PLL_BYPASS", bypass) &&
helper.ReadRegisterField("SCU", "PLLCON1", "ARM_PLL_CLKR", clkr) &&
helper.ReadRegisterField("SCU", "PLLCON1", "ARM_PLL_CLKF", clkf) &&
helper.ReadRegisterField("SCU", "PLLCON1", "ARM_PLL_CLKOD", clkod) &&
helper.ReadRegisterField("SCU", "PLLCON1", "ARM_PLL_POWERDOWN", pll_off))
if(ReadFieldOld("SCU", "PLLCON1", "ARM_PLL_BYPASS", bypass) &&
ReadFieldOld("SCU", "PLLCON1", "ARM_PLL_CLKR", clkr) &&
ReadFieldOld("SCU", "PLLCON1", "ARM_PLL_CLKF", clkf) &&
ReadFieldOld("SCU", "PLLCON1", "ARM_PLL_CLKOD", clkod) &&
ReadFieldOld("SCU", "PLLCON1", "ARM_PLL_POWERDOWN", pll_off))
{
arm_pll = AddClock(xtal_clk, "arm pll", pll_off ? DISABLED : FROM_PARENT,
bypass ? 1 : clkf+1, bypass ? 1 : (clkr+1)*(clkod+1));
@ -363,9 +391,9 @@ void ClockAnalyser::FillTreeRK27XX()
QTreeWidgetItem *arm_clk = 0;
QTreeWidgetItem *hclk = 0;
QTreeWidgetItem *pclk = 0;
if(helper.ReadRegisterField("SCU", "DIVCON1", "ARM_SLOW_MODE", value) &&
helper.ReadRegisterField("SCU", "DIVCON1", "ARM_CLK_DIV", value2) &&
helper.ReadRegisterField("SCU", "DIVCON1", "PCLK_CLK_DIV", value3))
if(ReadFieldOld("SCU", "DIVCON1", "ARM_SLOW_MODE", value) &&
ReadFieldOld("SCU", "DIVCON1", "ARM_CLK_DIV", value2) &&
ReadFieldOld("SCU", "DIVCON1", "PCLK_CLK_DIV", value3))
{
arm_clk = AddClock(value ? xtal_clk : arm_pll, "arm clk", FROM_PARENT, 1, value2 ? 2 : 1);
hclk = AddClock(arm_clk, "hclk", FROM_PARENT, 1, value2 ? 1 : 2);
@ -379,11 +407,11 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *dsp_pll = 0;
if (helper.ReadRegisterField("SCU", "PLLCON2", "DSP_PLL_BYPASS", bypass) &&
helper.ReadRegisterField("SCU", "PLLCON2", "DSP_PLL_CLKR", clkr) &&
helper.ReadRegisterField("SCU", "PLLCON2", "DSP_PLL_CLKF", clkf) &&
helper.ReadRegisterField("SCU", "PLLCON2", "DSP_PLL_CLKOD", clkod) &&
helper.ReadRegisterField("SCU", "PLLCON2", "DSP_PLL_POWERDOWN", pll_off))
if(ReadFieldOld("SCU", "PLLCON2", "DSP_PLL_BYPASS", bypass) &&
ReadFieldOld("SCU", "PLLCON2", "DSP_PLL_CLKR", clkr) &&
ReadFieldOld("SCU", "PLLCON2", "DSP_PLL_CLKF", clkf) &&
ReadFieldOld("SCU", "PLLCON2", "DSP_PLL_CLKOD", clkod) &&
ReadFieldOld("SCU", "PLLCON2", "DSP_PLL_POWERDOWN", pll_off))
{
dsp_pll = AddClock(xtal_clk, "dsp pll", pll_off ? DISABLED : FROM_PARENT,
bypass ? 1 : clkf+1, bypass ? 1 : (clkr+1)*(clkod+1));
@ -396,11 +424,11 @@ void ClockAnalyser::FillTreeRK27XX()
QTreeWidgetItem *dsp_clk = AddClock(dsp_pll, "dsp clk", FROM_PARENT);
QTreeWidgetItem *codec_pll = 0;
if (helper.ReadRegisterField("SCU", "PLLCON3", "CODEC_PLL_BYPASS", bypass) &&
helper.ReadRegisterField("SCU", "PLLCON3", "CODEC_PLL_CLKR", clkr) &&
helper.ReadRegisterField("SCU", "PLLCON3", "CODEC_PLL_CLKF", clkf) &&
helper.ReadRegisterField("SCU", "PLLCON3", "CODEC_PLL_CLKOD", clkod) &&
helper.ReadRegisterField("SCU", "PLLCON3", "CODEC_PLL_POWERDOWN", pll_off))
if(ReadFieldOld("SCU", "PLLCON3", "CODEC_PLL_BYPASS", bypass) &&
ReadFieldOld("SCU", "PLLCON3", "CODEC_PLL_CLKR", clkr) &&
ReadFieldOld("SCU", "PLLCON3", "CODEC_PLL_CLKF", clkf) &&
ReadFieldOld("SCU", "PLLCON3", "CODEC_PLL_CLKOD", clkod) &&
ReadFieldOld("SCU", "PLLCON3", "CODEC_PLL_POWERDOWN", pll_off))
{
codec_pll = AddClock(xtal_clk, "codec pll", pll_off ? DISABLED : FROM_PARENT,
bypass ? 1 : clkf+1, bypass ? 1 : (clkr+1)*(clkod+1));
@ -411,8 +439,8 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *codec_clk = 0;
if (helper.ReadRegisterField("SCU", "DIVCON1", "CODEC_CLK_SRC", value) &&
helper.ReadRegisterField("SCU", "DIVCON1", "CODEC_CLK_DIV", value2))
if(ReadFieldOld("SCU", "DIVCON1", "CODEC_CLK_SRC", value) &&
ReadFieldOld("SCU", "DIVCON1", "CODEC_CLK_DIV", value2))
{
codec_clk = AddClock(value ? xtal_clk : codec_pll, "codec clk", FROM_PARENT, 1, value ? 1 : (value2 + 1));
}
@ -422,7 +450,7 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *lsadc_clk = 0;
if (helper.ReadRegisterField("SCU", "DIVCON1", "LSADC_CLK_DIV", value))
if(ReadFieldOld("SCU", "DIVCON1", "LSADC_CLK_DIV", value))
{
lsadc_clk = AddClock(pclk, "lsadc clk", FROM_PARENT, 1, (value+1));
}
@ -432,11 +460,11 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *lcdc_clk = 0;
if (helper.ReadRegisterField("SCU", "DIVCON1", "LCDC_CLK", value) &&
helper.ReadRegisterField("SCU", "DIVCON1", "LCDC_CLK_DIV", value2) &&
helper.ReadRegisterField("SCU", "DIVCON1", "LCDC_CLK_DIV_SRC", value3))
if(ReadFieldOld("SCU", "DIVCON1", "LCDC_CLK", value) &&
ReadFieldOld("SCU", "DIVCON1", "LCDC_CLK_DIV", value2) &&
ReadFieldOld("SCU", "DIVCON1", "LCDC_CLK_DIV_SRC", value3))
{
if (value)
if(value)
{
lcdc_clk = AddClock(xtal_clk, "lcdc clk", FROM_PARENT);
}
@ -456,9 +484,9 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *pwm0_clk = 0;
if(helper.ReadRegisterField("PWM0", "LRC", "TR", value) &&
helper.ReadRegisterField("PWM0", "CTRL", "PRESCALE", value3) &&
helper.ReadRegisterField("PWM0", "CTRL", "PWM_EN", value4))
if(ReadFieldOld("PWM0", "LRC", "TR", value) &&
ReadFieldOld("PWM0", "CTRL", "PRESCALE", value3) &&
ReadFieldOld("PWM0", "CTRL", "PWM_EN", value4))
{
pwm0_clk = AddClock(pclk, "pwm0 clk", value4 ? FROM_PARENT : DISABLED, 1, 2*value*(1<<value3));
}
@ -468,9 +496,9 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *pwm1_clk = 0;
if(helper.ReadRegisterField("PWM1", "LRC", "TR", value) &&
helper.ReadRegisterField("PWM1", "CTRL", "PRESCALE", value3) &&
helper.ReadRegisterField("PWM1", "CTRL", "PWM_EN", value4))
if(ReadFieldOld("PWM1", "LRC", "TR", value) &&
ReadFieldOld("PWM1", "CTRL", "PRESCALE", value3) &&
ReadFieldOld("PWM1", "CTRL", "PWM_EN", value4))
{
pwm1_clk = AddClock(pclk, "pwm1 clk", value4 ? FROM_PARENT : DISABLED, 1, 2*value*(1<<value3));
}
@ -480,9 +508,9 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *pwm2_clk = 0;
if(helper.ReadRegisterField("PWM2", "LRC", "TR", value) &&
helper.ReadRegisterField("PWM2", "CTRL", "PRESCALE", value3) &&
helper.ReadRegisterField("PWM2", "CTRL", "PWM_EN", value4))
if(ReadFieldOld("PWM2", "LRC", "TR", value) &&
ReadFieldOld("PWM2", "CTRL", "PRESCALE", value3) &&
ReadFieldOld("PWM2", "CTRL", "PWM_EN", value4))
{
pwm2_clk = AddClock(pclk, "pwm2 clk", value4 ? FROM_PARENT : DISABLED, 1, 2*value*(1<<value3));
}
@ -492,9 +520,9 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *pwm3_clk = 0;
if(helper.ReadRegisterField("PWM3", "LRC", "TR", value) &&
helper.ReadRegisterField("PWM3", "CTRL", "PRESCALE", value3) &&
helper.ReadRegisterField("PWM3", "CTRL", "PWM_EN", value4))
if(ReadFieldOld("PWM3", "LRC", "TR", value) &&
ReadFieldOld("PWM3", "CTRL", "PRESCALE", value3) &&
ReadFieldOld("PWM3", "CTRL", "PWM_EN", value4))
{
pwm3_clk = AddClock(pclk, "pwm3", value4 ? FROM_PARENT : DISABLED, 1, 2*value*(1<<value3));
}
@ -504,7 +532,7 @@ void ClockAnalyser::FillTreeRK27XX()
}
QTreeWidgetItem *sdmmc_clk = 0;
if(helper.ReadRegisterField("SD", "CTRL", "DIVIDER", value))
if(ReadFieldOld("SD", "CTRL", "DIVIDER", value))
{
sdmmc_clk = AddClock(pclk, "sd clk", FROM_PARENT, 1, value+1);
}
@ -526,73 +554,72 @@ void ClockAnalyser::FillTreeRK27XX()
void ClockAnalyser::FillTreeIMX233()
{
BackendHelper helper(m_io_backend, m_soc);
soc_word_t value, value2, value3;
QTreeWidgetItem *ring_osc = 0;
if(helper.ReadRegisterField("POWER", "MINPWR", "ENABLE_OSC", value))
if(ReadFieldOld("POWER", "MINPWR", "ENABLE_OSC", value))
ring_osc = AddClock(0, "ring_clk24m", value ? 24000000 : DISABLED);
else
ring_osc = AddClock(0, "ring_clk24m", INVALID);
QTreeWidgetItem *xtal_osc = 0;
if(helper.ReadRegisterField("POWER", "MINPWR", "PWD_XTAL24", value))
if(ReadFieldOld("POWER", "MINPWR", "PWD_XTAL24", value))
xtal_osc = AddClock(0, "xtal_clk24m", value ? DISABLED : 24000000);
else
xtal_osc = AddClock(0, "xtal_clk24m", INVALID);
QTreeWidgetItem *ref_xtal = 0;
if(helper.ReadRegisterField("POWER", "MINPWR", "SELECT_OSC", value))
if(ReadFieldOld("POWER", "MINPWR", "SELECT_OSC", value))
ref_xtal = AddClock(value ? ring_osc : xtal_osc, "ref_xtal", FROM_PARENT);
else
ref_xtal = AddClock(0, "ref_xtal", INVALID);
QTreeWidgetItem *ref_pll = 0;
if(helper.ReadRegisterField("CLKCTRL", "PLLCTRL0", "POWER", value))
if(ReadFieldOld("CLKCTRL", "PLLCTRL0", "POWER", value))
ref_pll = AddClock(ref_xtal, "ref_pll", FROM_PARENT, 20);
else
ref_pll = AddClock(0, "ref_pll", INVALID);
QTreeWidgetItem *ref_io = 0;
if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEIO", value) &&
helper.ReadRegisterField("CLKCTRL", "FRAC", "IOFRAC", value2))
if(ReadFieldOld("CLKCTRL", "FRAC", "CLKGATEIO", value) &&
ReadFieldOld("CLKCTRL", "FRAC", "IOFRAC", value2))
ref_io = AddClock(ref_pll, "ref_io", value ? DISABLED : FROM_PARENT, 18, value2);
else
ref_io = AddClock(ref_pll, "ref_io", INVALID);
QTreeWidgetItem *ref_pix = 0;
if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEPIX", value) &&
helper.ReadRegisterField("CLKCTRL", "FRAC", "PIXFRAC", value2))
if(ReadFieldOld("CLKCTRL", "FRAC", "CLKGATEPIX", value) &&
ReadFieldOld("CLKCTRL", "FRAC", "PIXFRAC", value2))
ref_pix = AddClock(ref_pll, "ref_pix", value ? DISABLED : FROM_PARENT, 18, value2);
else
ref_pix = AddClock(ref_pll, "ref_pix", INVALID);
QTreeWidgetItem *ref_emi = 0;
if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEEMI", value) &&
helper.ReadRegisterField("CLKCTRL", "FRAC", "EMIFRAC", value2))
if(ReadFieldOld("CLKCTRL", "FRAC", "CLKGATEEMI", value) &&
ReadFieldOld("CLKCTRL", "FRAC", "EMIFRAC", value2))
ref_emi = AddClock(ref_pll, "ref_emi", value ? DISABLED : FROM_PARENT, 18, value2);
else
ref_emi = AddClock(ref_pll, "ref_emi", INVALID);
QTreeWidgetItem *ref_cpu = 0;
if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATECPU", value) &&
helper.ReadRegisterField("CLKCTRL", "FRAC", "CPUFRAC", value2))
if(ReadFieldOld("CLKCTRL", "FRAC", "CLKGATECPU", value) &&
ReadFieldOld("CLKCTRL", "FRAC", "CPUFRAC", value2))
ref_cpu = AddClock(ref_pll, "ref_cpu", value ? DISABLED : FROM_PARENT, 18, value2);
else
ref_cpu = AddClock(ref_pll, "ref_cpu", INVALID);
QTreeWidgetItem *clk_p = 0;
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_CPU", value))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_CPU", value))
{
if(!value)
{
if(helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_CPU", value2))
if(ReadFieldOld("CLKCTRL", "CPU", "DIV_CPU", value2))
clk_p = AddClock(ref_cpu, "clk_p", FROM_PARENT, 1, value2);
else
clk_p = AddClock(ref_cpu, "clk_p", INVALID);
}
else
{
if(helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_XTAL_FRAC_EN", value) &&
helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_XTAL", value2))
if(ReadFieldOld("CLKCTRL", "CPU", "DIV_XTAL_FRAC_EN", value) &&
ReadFieldOld("CLKCTRL", "CPU", "DIV_XTAL", value2))
clk_p = AddClock(ref_xtal, "clk_p", FROM_PARENT, value ? 1024 : 1, value2);
else
clk_p = AddClock(ref_xtal, "clk_p", INVALID);
@ -602,101 +629,101 @@ void ClockAnalyser::FillTreeIMX233()
clk_p = AddClock(ref_xtal, "clk_p", INVALID);
QTreeWidgetItem *clk_h = 0;
if(helper.ReadRegisterField("CLKCTRL", "HBUS", "DIV_FRAC_EN", value) &&
helper.ReadRegisterField("CLKCTRL", "HBUS", "DIV", value2))
if(ReadFieldOld("CLKCTRL", "HBUS", "DIV_FRAC_EN", value) &&
ReadFieldOld("CLKCTRL", "HBUS", "DIV", value2))
clk_h = AddClock(clk_p, "clk_h", FROM_PARENT, value ? 32 : 1, value2);
else
clk_h = AddClock(clk_p, "clk_h", INVALID);
QTreeWidgetItem *clk_x = 0;
if(helper.ReadRegisterField("CLKCTRL", "XBUS", "DIV", value))
if(ReadFieldOld("CLKCTRL", "XBUS", "DIV", value))
clk_x = AddClock(ref_xtal, "clk_x", FROM_PARENT, 1, value);
else
clk_x = AddClock(ref_xtal, "clk_x", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "UART_CLK_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "UART_CLK_GATE", value))
AddClock(ref_xtal, "clk_uart", value ? DISABLED : FROM_PARENT);
else
AddClock(ref_xtal, "clk_uart", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "FILT_CLK24M_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "FILT_CLK24M_GATE", value))
AddClock(ref_xtal, "clk_filt24m", value ? DISABLED : FROM_PARENT);
else
AddClock(ref_xtal, "clk_filt24m", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "PWM_CLK24M_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "PWM_CLK24M_GATE", value))
AddClock(ref_xtal, "clk_pwm24m", value ? DISABLED : FROM_PARENT);
else
AddClock(ref_xtal, "clk_pwm24m", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "DRI_CLK24M_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "DRI_CLK24M_GATE", value))
AddClock(ref_xtal, "clk_dri24m", value ? DISABLED : FROM_PARENT);
else
AddClock(ref_xtal, "clk_dri24m", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "DIGCTRL_CLK1M_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "DIGCTRL_CLK1M_GATE", value))
AddClock(ref_xtal, "clk_1m", value ? DISABLED : FROM_PARENT, 1, 24);
else
AddClock(ref_xtal, "clk_1m", INVALID);
QTreeWidgetItem *clk_32k = 0;
if(helper.ReadRegisterField("CLKCTRL", "XTAL", "TIMROT_CLK32K_GATE", value))
if(ReadFieldOld("CLKCTRL", "XTAL", "TIMROT_CLK32K_GATE", value))
clk_32k = AddClock(ref_xtal, "clk_32k", value ? DISABLED : FROM_PARENT, 1, 750);
else
clk_32k = AddClock(ref_xtal, "clk_32k", INVALID);
AddClock(clk_32k, "clk_adc", FROM_PARENT, 1, 16);
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_PIX", value) &&
helper.ReadRegisterField("CLKCTRL", "PIX", "DIV", value2))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_PIX", value) &&
ReadFieldOld("CLKCTRL", "PIX", "DIV", value2))
AddClock(value ? ref_xtal : ref_pix, "clk_pix", FROM_PARENT, 1, value2);
else
AddClock(ref_xtal, "clk_p", INVALID);
QTreeWidgetItem *clk_ssp = 0;
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_SSP", value) &&
helper.ReadRegisterField("CLKCTRL", "SSP", "DIV", value2) &&
helper.ReadRegisterField("CLKCTRL", "SSP", "CLKGATE", value3))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_SSP", value) &&
ReadFieldOld("CLKCTRL", "SSP", "DIV", value2) &&
ReadFieldOld("CLKCTRL", "SSP", "CLKGATE", value3))
clk_ssp = AddClock(value ? ref_xtal : ref_io, "clk_ssp", value3 ? DISABLED : FROM_PARENT, 1, value2);
else
clk_ssp = AddClock(ref_xtal, "clk_p", INVALID);
if(helper.ReadRegisterField("SSP1", "TIMING", "CLOCK_DIVIDE", value) &&
helper.ReadRegisterField("SSP1", "TIMING", "CLOCK_RATE", value2) &&
helper.ReadRegisterField("SSP1", "CTRL0", "CLKGATE", value3))
if(ReadFieldOld("SSP1", "TIMING", "CLOCK_DIVIDE", value) &&
ReadFieldOld("SSP1", "TIMING", "CLOCK_RATE", value2) &&
ReadFieldOld("SSP1", "CTRL0", "CLKGATE", value3))
AddClock(clk_ssp, "clk_ssp1", value3 ? DISABLED : FROM_PARENT, 1, value * (1 + value2));
else
AddClock(clk_ssp, "clk_ssp1", INVALID);
if(helper.ReadRegisterField("SSP2", "TIMING", "CLOCK_DIVIDE", value) &&
helper.ReadRegisterField("SSP2", "TIMING", "CLOCK_RATE", value2) &&
helper.ReadRegisterField("SSP2", "CTRL0", "CLKGATE", value3))
if(ReadFieldOld("SSP2", "TIMING", "CLOCK_DIVIDE", value) &&
ReadFieldOld("SSP2", "TIMING", "CLOCK_RATE", value2) &&
ReadFieldOld("SSP2", "CTRL0", "CLKGATE", value3))
AddClock(clk_ssp, "clk_ssp2", value3 ? DISABLED : FROM_PARENT, 1, value * (1 + value2));
else
AddClock(clk_ssp, "clk_ssp2", INVALID);
QTreeWidgetItem *clk_gpmi = 0;
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_GPMI", value) &&
helper.ReadRegisterField("CLKCTRL", "GPMI", "DIV", value2) &&
helper.ReadRegisterField("CLKCTRL", "GPMI", "CLKGATE", value3))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_GPMI", value) &&
ReadFieldOld("CLKCTRL", "GPMI", "DIV", value2) &&
ReadFieldOld("CLKCTRL", "GPMI", "CLKGATE", value3))
clk_gpmi = AddClock(value ? ref_xtal : ref_io, "clk_gpmi", value3 ? DISABLED : FROM_PARENT, 1, value2);
else
clk_gpmi = AddClock(ref_xtal, "clk_p", INVALID);
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value))
{
if(!value)
{
if(helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_EMI", value2) &&
helper.ReadRegisterField("CLKCTRL", "EMI", "CLKGATE", value3))
if(ReadFieldOld("CLKCTRL", "EMI", "DIV_EMI", value2) &&
ReadFieldOld("CLKCTRL", "EMI", "CLKGATE", value3))
AddClock(ref_emi, "clk_emi", value3 ? DISABLED : FROM_PARENT, 1, value2);
else
AddClock(ref_emi, "clk_emi", INVALID);
}
else
{
if(helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_XTAL", value2) &&
helper.ReadRegisterField("CLKCTRL", "EMI", "CLKGATE", value3))
if(ReadFieldOld("CLKCTRL", "EMI", "DIV_XTAL", value2) &&
ReadFieldOld("CLKCTRL", "EMI", "CLKGATE", value3))
AddClock(ref_xtal, "clk_emi", value3 ? DISABLED : FROM_PARENT, 1, value2);
else
AddClock(ref_xtal, "clk_emi", INVALID);
@ -707,27 +734,27 @@ void ClockAnalyser::FillTreeIMX233()
QTreeWidgetItem *ref_vid = AddClock(ref_pll, "clk_vid", FROM_PARENT);
if(helper.ReadRegisterField("CLKCTRL", "TV", "CLK_TV108M_GATE", value) &&
helper.ReadRegisterField("CLKCTRL", "TV", "CLK_TV_GATE", value2))
if(ReadFieldOld("CLKCTRL", "TV", "CLK_TV108M_GATE", value) &&
ReadFieldOld("CLKCTRL", "TV", "CLK_TV_GATE", value2))
{
QTreeWidgetItem *clk_tv108m = AddClock(ref_vid, "clk_tv108m", value ? DISABLED : FROM_PARENT, 1, 4);
AddClock(clk_tv108m, "clk_tv54m", value2 ? DISABLED : FROM_PARENT, 1, 2);
AddClock(clk_tv108m, "clk_tv27m", value2 ? DISABLED : FROM_PARENT, 1, 4);
}
if(helper.ReadRegisterField("CLKCTRL", "PLLCTRL0", "EN_USB_CLKS", value))
if(ReadFieldOld("CLKCTRL", "PLLCTRL0", "EN_USB_CLKS", value))
AddClock(ref_pll, "utmi_clk480m", value ? FROM_PARENT : DISABLED);
else
AddClock(ref_pll, "utmi_clk480m", INVALID);
QTreeWidgetItem *xtal_clk32k = 0;
if(helper.ReadRegisterField("RTC", "PERSISTENT0", "XTAL32_FREQ", value) &&
helper.ReadRegisterField("RTC", "PERSISTENT0", "XTAL32KHZ_PWRUP", value2))
if(ReadFieldOld("RTC", "PERSISTENT0", "XTAL32_FREQ", value) &&
ReadFieldOld("RTC", "PERSISTENT0", "XTAL32KHZ_PWRUP", value2))
xtal_clk32k = AddClock(0, "xtal_clk32k", value2 == 0 ? DISABLED : value ? 32000 : 32768);
else
xtal_clk32k = AddClock(0, "xtal_clk32k", INVALID);
if(helper.ReadRegisterField("RTC", "PERSISTENT0", "CLOCKSOURCE", value))
if(ReadFieldOld("RTC", "PERSISTENT0", "CLOCKSOURCE", value))
AddClock(value ? xtal_clk32k : ref_xtal, "clk_rtc32k", FROM_PARENT, 1, value ? 1 : 768);
else
AddClock(ref_xtal, "clk_rtc32k", INVALID);
@ -742,8 +769,8 @@ static TmplAnalyserFactory< ClockAnalyser > g_clock_factory(true, "Clock Analyse
/**
* EMI analyser
*/
EmiAnalyser::EmiAnalyser(const SocRef& soc, IoBackend *backend)
:Analyser(soc, backend)
EmiAnalyser::EmiAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend)
:AnalyserEx(soc, backend)
{
m_display_mode = DisplayCycles;
m_group = new QGroupBox("EMI Analyser");
@ -870,26 +897,25 @@ void EmiAnalyser::FillTable()
{
while(m_panel->count() > 0)
m_panel->removeItem(0);
BackendHelper helper(m_io_backend, m_soc);
soc_word_t value;
m_emi_freq = 0;
if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value))
if(ReadFieldOld("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value))
{
bool ret;
if(value)
{
m_emi_freq = 24000000;
ret = helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_XTAL", value);
ret = ReadFieldOld("CLKCTRL", "EMI", "DIV_XTAL", value);
}
else
{
m_emi_freq = 480000000;
if(helper.ReadRegisterField("CLKCTRL", "FRAC", "EMIFRAC", value))
if(ReadFieldOld("CLKCTRL", "FRAC", "EMIFRAC", value))
m_emi_freq = 18 * (int64_t)m_emi_freq / value;
else
m_emi_freq = 0;
ret = helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_EMI", value);
ret = ReadFieldOld("CLKCTRL", "EMI", "DIV_EMI", value);
}
if(ret)
m_emi_freq /= value;
@ -900,7 +926,7 @@ void EmiAnalyser::FillTable()
m_emi_freq_label->setText(QString().sprintf("%.3f", m_emi_freq / 1000000.0));
NewGroup("Control Parameters");
if(helper.ReadRegisterField("EMI", "CTRL", "PORT_PRIORITY_ORDER", value))
if(ReadFieldOld("EMI", "CTRL", "PORT_PRIORITY_ORDER", value))
{
QStringList ports;
ports << "AXI0" << "AHB1" << "AHB2" << "AHB3";
@ -913,38 +939,38 @@ void EmiAnalyser::FillTable()
AddLine("Port Priority Order", value, "", order);
}
if(helper.ReadRegisterField("EMI", "CTRL", "MEM_WIDTH", value))
if(ReadFieldOld("EMI", "CTRL", "MEM_WIDTH", value))
AddLine("Memory Width", value ? 16 : 8, "-bit");
if(helper.ReadRegisterField("DRAM", "CTL03", "AP", value))
if(ReadFieldOld("DRAM", "CTL03", "AP", value))
AddLine("Auto Pre-Charge", NONE, value ? "Yes" : "No");
bool bypass_mode = false;
if(helper.ReadRegisterField("DRAM", "CTL04", "DLL_BYPASS_MODE", value))
if(ReadFieldOld("DRAM", "CTL04", "DLL_BYPASS_MODE", value))
{
bypass_mode = value == 1;
AddLine("DLL Bypass Mode", NONE, value ? "Yes" : "No");
}
if(helper.ReadRegisterField("DRAM", "CTL05", "EN_LOWPOWER_MODE", value))
if(ReadFieldOld("DRAM", "CTL05", "EN_LOWPOWER_MODE", value))
AddLine("Low Power Mode", NONE, value ? "Enabled" : "Disabled");
if(helper.ReadRegisterField("DRAM", "CTL08", "SREFRESH", value))
if(ReadFieldOld("DRAM", "CTL08", "SREFRESH", value))
AddLine("Self Refresh", NONE, value ? "Yes" : "No");
if(helper.ReadRegisterField("DRAM", "CTL08", "SDR_MODE", value))
if(ReadFieldOld("DRAM", "CTL08", "SDR_MODE", value))
AddLine("Mode", NONE, value ? "SDR" : "DDR");
if(helper.ReadRegisterField("DRAM", "CTL10", "ADDR_PINS", value))
if(ReadFieldOld("DRAM", "CTL10", "ADDR_PINS", value))
AddLine("Address Pins", 13 - value, "");
if(helper.ReadRegisterField("DRAM", "CTL11", "COLUMN_SIZE", value))
if(ReadFieldOld("DRAM", "CTL11", "COLUMN_SIZE", value))
AddLine("Column Size", 12 - value, "-bit");
if(helper.ReadRegisterField("DRAM", "CTL11", "CASLAT", value))
if(ReadFieldOld("DRAM", "CTL11", "CASLAT", value))
AddLine("Encoded CAS", value, "", "Memory device dependent");
if(helper.ReadRegisterField("DRAM", "CTL14", "CS_MAP", value))
if(ReadFieldOld("DRAM", "CTL14", "CS_MAP", value))
{
QString v;
for(int i = 0; i < 4; i++)
@ -957,12 +983,12 @@ void EmiAnalyser::FillTable()
AddLine("Chip Select Pins", NONE, v, "");
}
if(helper.ReadRegisterField("DRAM", "CTL37", "TREF_ENABLE", value))
if(ReadFieldOld("DRAM", "CTL37", "TREF_ENABLE", value))
AddLine("Refresh Commands", NONE, value ? "Enabled" : "Disabled", "Issue self-refresh every TREF cycles");
NewGroup("Frequency Parameters");
if(helper.ReadRegisterField("DRAM", "CTL13", "CASLAT_LIN_GATE", value))
if(ReadFieldOld("DRAM", "CTL13", "CASLAT_LIN_GATE", value))
{
if(value >= 3 && value <= 10 && value != 9)
{
@ -972,7 +998,7 @@ void EmiAnalyser::FillTable()
else
AddLine("CAS Gate", NONE, "Reserved", "Reserved value");
}
if(helper.ReadRegisterField("DRAM", "CTL13", "CASLAT_LIN", value))
if(ReadFieldOld("DRAM", "CTL13", "CASLAT_LIN", value))
{
if(value >= 3 && value <= 10 && value != 9)
{
@ -983,97 +1009,97 @@ void EmiAnalyser::FillTable()
AddLine("CAS Latency", NONE, "Reserved", "Reserved value");
}
if(helper.ReadRegisterField("DRAM", "CTL12", "TCKE", value))
if(ReadFieldOld("DRAM", "CTL12", "TCKE", value))
AddCycleLine("tCKE", value, value, 0, "Minimum CKE pulse width");
if(helper.ReadRegisterField("DRAM", "CTL15", "TDAL", value))
if(ReadFieldOld("DRAM", "CTL15", "TDAL", value))
AddCycleLine("tDAL", value, value, 0, "Auto pre-charge write recovery time");
if(helper.ReadRegisterField("DRAM", "CTL31", "TDLL", value))
if(ReadFieldOld("DRAM", "CTL31", "TDLL", value))
AddCycleLine("tDLL", value, value, 0, "DLL lock time");
if(helper.ReadRegisterField("DRAM", "CTL10", "TEMRS", value))
if(ReadFieldOld("DRAM", "CTL10", "TEMRS", value))
AddCycleLine("tEMRS", value, value, 0, "Extended mode parameter set time");
if(helper.ReadRegisterField("DRAM", "CTL34", "TINIT", value))
if(ReadFieldOld("DRAM", "CTL34", "TINIT", value))
AddCycleLine("tINIT", value, value, 0, "Initialisation time");
if(helper.ReadRegisterField("DRAM", "CTL16", "TMRD", value))
if(ReadFieldOld("DRAM", "CTL16", "TMRD", value))
AddCycleLine("tMRD", value, value, 0, "Mode register set command time");
if(helper.ReadRegisterField("DRAM", "CTL40", "TPDEX", value))
if(ReadFieldOld("DRAM", "CTL40", "TPDEX", value))
AddCycleLine("tPDEX", value, value, 0, "Power down exit time");
if(helper.ReadRegisterField("DRAM", "CTL32", "TRAS_MAX", value))
if(ReadFieldOld("DRAM", "CTL32", "TRAS_MAX", value))
AddCycleLine("tRAS Max", value, value, 0, "Maximum row activate time");
if(helper.ReadRegisterField("DRAM", "CTL20", "TRAS_MIN", value))
if(ReadFieldOld("DRAM", "CTL20", "TRAS_MIN", value))
AddCycleLine("tRAS Min", value, value, 0, "Minimum row activate time");
if(helper.ReadRegisterField("DRAM", "CTL17", "TRC", value))
if(ReadFieldOld("DRAM", "CTL17", "TRC", value))
AddCycleLine("tRC", value, value, 0, "Activate to activate delay (same bank)");
if(helper.ReadRegisterField("DRAM", "CTL20", "TRCD_INT", value))
if(ReadFieldOld("DRAM", "CTL20", "TRCD_INT", value))
AddCycleLine("tRCD", value, value, 0, "RAS to CAS");
if(helper.ReadRegisterField("DRAM", "CTL26", "TREF", value))
if(ReadFieldOld("DRAM", "CTL26", "TREF", value))
AddCycleLine("tREF", value, value, 0, "Refresh to refresh time");
if(helper.ReadRegisterField("DRAM", "CTL21", "TRFC", value))
if(ReadFieldOld("DRAM", "CTL21", "TRFC", value))
AddCycleLine("tRFC", value, value, 0, "Refresh command time");
if(helper.ReadRegisterField("DRAM", "CTL15", "TRP", value))
if(ReadFieldOld("DRAM", "CTL15", "TRP", value))
AddCycleLine("tRP", value, value, 0, "Pre-charge command time");
if(helper.ReadRegisterField("DRAM", "CTL12", "TRRD", value))
if(ReadFieldOld("DRAM", "CTL12", "TRRD", value))
AddCycleLine("tRRD", value, value, 0, "Activate to activate delay (different banks)");
if(helper.ReadRegisterField("DRAM", "CTL12", "TWR_INT", value))
if(ReadFieldOld("DRAM", "CTL12", "TWR_INT", value))
AddCycleLine("tWR", value, value, 0, "Write recovery time");
if(helper.ReadRegisterField("DRAM", "CTL13", "TWTR", value))
if(ReadFieldOld("DRAM", "CTL13", "TWTR", value))
AddCycleLine("tWTR", value, value, 0, "Write to read delay");
if(helper.ReadRegisterField("DRAM", "CTL32", "TXSNR", value))
if(ReadFieldOld("DRAM", "CTL32", "TXSNR", value))
AddCycleLine("tXSNR", value, value, 0, "");
if(helper.ReadRegisterField("DRAM", "CTL33", "TXSR", value))
if(ReadFieldOld("DRAM", "CTL33", "TXSR", value))
AddCycleLine("tXSR", value, value, 0, "Self-refresh exit time");
NewGroup("DLL Parameters");
if(bypass_mode)
{
if(helper.ReadRegisterField("DRAM", "CTL19", "DLL_DQS_DELAY_BYPASS_0", value))
if(ReadFieldOld("DRAM", "CTL19", "DLL_DQS_DELAY_BYPASS_0", value))
AddLine("DLL DQS Delay 0", value, "", "In 1/128 fraction of a cycle (bypass mode)");
if(helper.ReadRegisterField("DRAM", "CTL19", "DLL_DQS_DELAY_BYPASS_0", value))
if(ReadFieldOld("DRAM", "CTL19", "DLL_DQS_DELAY_BYPASS_0", value))
AddLine("DLL DQS Delay 1", value, "", "In 1/128 fraction of a cycle (bypass mode)");
if(helper.ReadRegisterField("DRAM", "CTL19", "DQS_OUT_SHIFT_BYPASS", value))
if(ReadFieldOld("DRAM", "CTL19", "DQS_OUT_SHIFT_BYPASS", value))
AddLine("DQS Out Delay", value, "", "(bypass mode)");
if(helper.ReadRegisterField("DRAM", "CTL20", "WR_DQS_SHIFT_BYPASS", value))
if(ReadFieldOld("DRAM", "CTL20", "WR_DQS_SHIFT_BYPASS", value))
AddLine("DQS Write Delay", value, "", "(bypass mode)");
}
else
{
if(helper.ReadRegisterField("DRAM", "CTL17", "DLL_START_POINT", value))
if(ReadFieldOld("DRAM", "CTL17", "DLL_START_POINT", value))
AddLine("DLL Start Point", value, "", "Initial delay count");
if(helper.ReadRegisterField("DRAM", "CTL17", "DLL_INCREMENT", value))
if(ReadFieldOld("DRAM", "CTL17", "DLL_INCREMENT", value))
AddLine("DLL Increment", value, "", "Delay increment");
if(helper.ReadRegisterField("DRAM", "CTL18", "DLL_DQS_DELAY_0", value))
if(ReadFieldOld("DRAM", "CTL18", "DLL_DQS_DELAY_0", value))
AddLine("DLL DQS Delay 0", value, "", "In 1/128 fraction of a cycle");
if(helper.ReadRegisterField("DRAM", "CTL18", "DLL_DQS_DELAY_1", value))
if(ReadFieldOld("DRAM", "CTL18", "DLL_DQS_DELAY_1", value))
AddLine("DLL DQS Delay 1", value, "", "In 1/128 fraction of a cycle");
if(helper.ReadRegisterField("DRAM", "CTL19", "DQS_OUT_SHIFT", value))
if(ReadFieldOld("DRAM", "CTL19", "DQS_OUT_SHIFT", value))
AddLine("DQS Out Delay", value, "", "");
if(helper.ReadRegisterField("DRAM", "CTL20", "WR_DQS_SHIFT", value))
if(ReadFieldOld("DRAM", "CTL20", "WR_DQS_SHIFT", value))
AddLine("DQS Write Delay", value, "", "");
}
@ -1090,8 +1116,8 @@ namespace pin_desc
#include "../../imxtools/misc/map.h"
}
PinAnalyser::PinAnalyser(const SocRef& soc, IoBackend *backend)
:Analyser(soc, backend)
PinAnalyser::PinAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend)
:AnalyserEx(soc, backend)
{
m_group = new QGroupBox("Pin Analyser");
QVBoxLayout *layout = new QVBoxLayout;
@ -1129,7 +1155,6 @@ bool PinAnalyser::SupportSoc(const QString& soc_name)
void PinAnalyser::FillList()
{
BackendHelper helper(m_io_backend, m_soc);
soc_word_t value;
while(m_panel->count() > 0)
@ -1140,7 +1165,7 @@ void PinAnalyser::FillList()
"bga169", "bga100", "lqfp100", "lqfp128", 0, 0, 0, 0
};
if(!helper.ReadRegisterField("DIGCTL", "STATUS", "PACKAGE_TYPE", value))
if(!ReadFieldOld("DIGCTL", "STATUS", "PACKAGE_TYPE", value))
{
m_package_edit->setText("<read error>");
return;
@ -1199,21 +1224,21 @@ void PinAnalyser::FillList()
uint32_t muxsel[2], drive[4], pull, in, out, oe;
bool error = false;
for(int i = 0; i < 2; i++)
if(!helper.ReadRegister("PINCTRL", QString("MUXSEL%1").arg(bank * 2 + i), muxsel[i]))
if(!ReadRegisterOld("PINCTRL", QString("MUXSELn[%1]").arg(bank * 2 + i), muxsel[i]))
error = true;
/* don't make an error for those since some do not exist */
for(int i = 0; i < 4; i++)
if(!helper.ReadRegister("PINCTRL", QString("DRIVE%1").arg(bank * 4 + i), drive[i]))
if(!ReadRegisterOld("PINCTRL", QString("DRIVEn[%1]").arg(bank * 4 + i), drive[i]))
drive[i] = 0;
if(error)
continue;
if(!helper.ReadRegister("PINCTRL", QString("PULL%1").arg(bank), pull))
if(!ReadRegisterOld("PINCTRL", QString("PULLn[%1]").arg(bank), pull))
pull = 0;
if(!helper.ReadRegister("PINCTRL", QString("DIN%1").arg(bank), in))
if(!ReadRegisterOld("PINCTRL", QString("DINn[%1]").arg(bank), in))
in = 0;
if(!helper.ReadRegister("PINCTRL", QString("DOUT%1").arg(bank), out))
if(!ReadRegisterOld("PINCTRL", QString("DOUTn[%1]").arg(bank), out))
out = 0;
if(!helper.ReadRegister("PINCTRL", QString("DOE%1").arg(bank), oe))
if(!ReadRegisterOld("PINCTRL", QString("DOEn[%1]").arg(bank), oe))
oe = 0;
for(int pin = 0; pin < 32; pin++)

View file

@ -35,14 +35,28 @@
#include <QLineEdit>
#include "analyser.h"
class AnalyserEx : public Analyser
{
public:
AnalyserEx(const soc_desc::soc_ref_t& soc, IoBackend *backend);
protected:
bool ReadRegister(const QString& path, soc_word_t& val);
bool ReadRegisterOld(const QString& dev, const QString& reg, soc_word_t& val);
bool ReadField(const QString& path, const QString& field, soc_word_t& val);
bool ReadFieldOld(const QString& dev, const QString& reg, const QString& field,
soc_word_t& val);
BackendHelper m_helper;
};
/**
* Clock analyser
*/
class ClockAnalyser : public Analyser
class ClockAnalyser : public AnalyserEx
{
public:
ClockAnalyser(const SocRef& soc, IoBackend *backend);
ClockAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend);
virtual ~ClockAnalyser();
virtual QWidget *GetWidget();
static bool SupportSoc(const QString& soc_name);
@ -72,11 +86,11 @@ private:
/**
* EMI analyser
*/
class EmiAnalyser : public QObject, public Analyser
class EmiAnalyser : public QObject, public AnalyserEx
{
Q_OBJECT
public:
EmiAnalyser(const SocRef& soc, IoBackend *backend);
EmiAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend);
virtual ~EmiAnalyser();
virtual QWidget *GetWidget();
@ -116,10 +130,10 @@ private:
/**
* PINCTRL analyzer
*/
class PinAnalyser : public Analyser
class PinAnalyser : public AnalyserEx
{
public:
PinAnalyser(const SocRef& soc, IoBackend *backend);
PinAnalyser(const soc_desc::soc_ref_t& soc, IoBackend *backend);
virtual ~PinAnalyser();
virtual QWidget *GetWidget();

View file

@ -29,6 +29,7 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QTextBlock>
#include <QApplication>
/**
* SocBitRangeValidator
@ -36,6 +37,7 @@
SocBitRangeValidator::SocBitRangeValidator(QObject *parent)
:QValidator(parent)
{
m_width = 32;
}
void SocBitRangeValidator::fixup(QString& input) const
@ -66,11 +68,11 @@ QValidator::State SocBitRangeValidator::parse(const QString& input, int& last, i
// parse last bit and check it's between 0 and 31
bool ok = false;
last = input.left(pos).toInt(&ok);
if(!ok || last < 0 || last >= 32)
if(!ok || last < 0 || last >= m_width)
return Invalid;
}
else
last = 31;
last = m_width - 1;
// parse first bit
if(pos < input.size() - 1)
{
@ -88,6 +90,19 @@ QValidator::State SocBitRangeValidator::parse(const QString& input, int& last, i
return Acceptable;
}
void SocBitRangeValidator::setWidth(int nr_bits)
{
m_width = nr_bits;
}
QString SocBitRangeValidator::generate(int last_bit, int first_bit) const
{
if(last_bit == first_bit)
return QString("%1").arg(first_bit);
else
return QString("%1:%2").arg(last_bit).arg(first_bit);
}
/**
* SocFieldValidator
*/
@ -95,11 +110,11 @@ QValidator::State SocBitRangeValidator::parse(const QString& input, int& last, i
SocFieldValidator::SocFieldValidator(QObject *parent)
:QValidator(parent)
{
m_field.first_bit = 0;
m_field.last_bit = 31;
m_field.pos = 0;
m_field.width = 32;
}
SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent)
SocFieldValidator::SocFieldValidator(const soc_desc::field_t& field, QObject *parent)
:QValidator(parent), m_field(field)
{
}
@ -124,7 +139,7 @@ QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val
return Intermediate;
// first check named values
State state = Invalid;
foreach(const soc_reg_field_value_t& value, m_field.value)
foreach(const soc_desc::enum_t& value, m_field.enum_)
{
QString name = QString::fromLocal8Bit(value.name.c_str());
// cannot be a substring if too long or empty
@ -176,7 +191,7 @@ QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val
if(!ok)
return state;
// if ok, check if it fits in the number of bits
unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1;
unsigned nr_bits = m_field.width;
unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1;
if(v <= max)
{
@ -308,14 +323,22 @@ QString SocFieldItemDelegate::displayText(const QVariant& value, const QLocale&
return QStyledItemDelegate::displayText(value, locale);
}
void SocFieldItemDelegate::setWidth(int bitcount)
{
m_bitcount = bitcount;
}
/**
* SocFieldEditor
*/
SocFieldEditor::SocFieldEditor(const soc_reg_field_t& field, QWidget *parent)
SocFieldEditor::SocFieldEditor(const soc_desc::field_t& field, QWidget *parent)
:QLineEdit(parent), m_reg_field(field)
{
m_validator = new SocFieldValidator(field);
setValidator(m_validator);
connect(this, SIGNAL(editingFinished()), this, SLOT(editDone()));
setAlignment(Qt::AlignCenter);
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
}
SocFieldEditor::~SocFieldEditor()
@ -323,6 +346,11 @@ SocFieldEditor::~SocFieldEditor()
delete m_validator;
}
void SocFieldEditor::editDone()
{
emit editingFinished(field());
}
uint SocFieldEditor::field() const
{
soc_word_t v;
@ -336,11 +364,11 @@ uint SocFieldEditor::field() const
void SocFieldEditor::setField(uint field)
{
m_field = field;
int digits = (m_reg_field.last_bit - m_reg_field.first_bit + 4) / 4;
int digits = (m_reg_field.width + 3) / 4;
setText(QString("0x%1").arg(field, digits, 16, QChar('0')));
}
void SocFieldEditor::SetRegField(const soc_reg_field_t& field)
void SocFieldEditor::SetRegField(const soc_desc::field_t& field)
{
setValidator(0);
delete m_validator;
@ -352,12 +380,30 @@ void SocFieldEditor::SetRegField(const soc_reg_field_t& field)
/**
* SocFieldCachedValue
*/
SocFieldCachedValue::SocFieldCachedValue(const soc_reg_field_t& field, uint value)
SocFieldCachedValue::SocFieldCachedValue(const soc_desc::field_t& field, uint value)
:m_field(field), m_value(value)
{
int idx = field.find_value(value);
if(idx != -1)
m_name = QString::fromStdString(field.value[idx].name);
m_name = QString::fromStdString(field.enum_[idx].name);
}
bool SocFieldCachedValue::operator<(const SocFieldCachedValue& o) const
{
return m_value < o.m_value;
}
/**
* SocFieldBitRange
*/
bool SocFieldBitRange::operator<(const SocFieldBitRange& o) const
{
if(m_first_bit < o.m_first_bit)
return true;
if(m_first_bit > o.m_first_bit)
return false;
return m_last_bit < o.m_last_bit;
}
/**
@ -372,11 +418,10 @@ SocFieldCachedItemDelegate::SocFieldCachedItemDelegate(QObject *parent)
QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLocale& locale) const
{
// FIXME see QTBUG-30392
if(value.type() == QVariant::UserType && value.userType() == qMetaTypeId< SocFieldCachedValue >())
if(isUserType< SocFieldCachedValue >(value))
{
const SocFieldCachedValue& v = value.value< SocFieldCachedValue >();
int bitcount = v.field().last_bit - v.field().first_bit;
int bitcount = v.field().width;
QString name = v.value_name();
QString strval = QString("0x%1").arg(v.value(), (bitcount + 3) / 4, 16, QChar('0'));
switch(m_mode)
@ -410,7 +455,7 @@ QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLo
* SocFieldCachedEditor
*/
SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent)
:SocFieldEditor(soc_reg_field_t(), parent)
:SocFieldEditor(soc_desc::field_t(), parent)
{
}
@ -443,6 +488,11 @@ QByteArray SocFieldEditorCreator::valuePropertyName() const
return QByteArray("field");
}
void SocFieldEditorCreator::setWidth(int bitcount)
{
m_field.width = bitcount;
}
/**
* SocFieldCachedEditorCreator
*/
@ -478,8 +528,10 @@ int RegFieldTableModel::columnCount(const QModelIndex& /* parent */) const
QVariant RegFieldTableModel::data(const QModelIndex& index, int role) const
{
if(index.row() < 0 || (size_t)index.row() >= m_reg.field.size())
return QVariant();
int section = index.column();
const soc_reg_field_t& field = m_reg.field[index.row()];
const soc_desc::field_t& field = m_reg.field[index.row()];
/* column independent code */
const RegThemeGroup *theme = 0;
switch(m_status[index.row()])
@ -609,7 +661,7 @@ void RegFieldTableModel::SetReadOnly(bool en)
m_read_only = en;
}
void RegFieldTableModel::SetRegister(const soc_reg_t& reg)
void RegFieldTableModel::SetRegister(const soc_desc::register_t& reg)
{
/* remove all rows */
beginResetModel();
@ -622,6 +674,18 @@ void RegFieldTableModel::SetRegister(const soc_reg_t& reg)
endInsertRows();
}
void RegFieldTableModel::UpdateRegister(const soc_desc::register_t& reg)
{
m_reg = reg;
RecomputeTheme();
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}
soc_desc::register_t RegFieldTableModel::GetRegister() const
{
return m_reg;
}
void RegFieldTableModel::SetValues(const QVector< QVariant >& values)
{
/* remove all value columns */
@ -658,7 +722,7 @@ void RegFieldTableModel::RecomputeTheme()
if(!m_theme.valid || m_value.size() == 0)
continue;
m_status[i] = Normal;
const soc_reg_field_t& field = m_reg.field[i];
const soc_desc::field_t& field = m_reg.field[i];
QVariant val;
for(int j = 0; j < m_value.size(); j++)
{
@ -675,120 +739,269 @@ void RegFieldTableModel::RecomputeTheme()
}
/**
* RegSexyDisplay2
* RegFieldProxyModel
*/
RegSexyDisplay2::RegSexyDisplay2(QWidget *parent)
bool RegFieldProxyModel::lessThan(const QModelIndex& left,
const QModelIndex& right) const
{
QVariant ldata = sourceModel()->data(left);
QVariant rdata = sourceModel()->data(right);
if(isUserType< SocFieldBitRange >(ldata) &&
isUserType< SocFieldBitRange >(rdata))
{
return ldata.value< SocFieldBitRange >() <
rdata.value< SocFieldBitRange >();
}
else if(isUserType< SocFieldCachedValue >(ldata) &&
isUserType< SocFieldCachedValue >(rdata))
{
return ldata.value< SocFieldCachedValue >() <
rdata.value< SocFieldCachedValue >();
}
else
return QSortFilterProxyModel::lessThan(left, right);
}
/**
* YRegDisplayItemDelegate
*/
YRegDisplayItemDelegate::YRegDisplayItemDelegate(QObject *parent)
:QStyledItemDelegate(parent)
{
}
void YRegDisplayItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QStyleOptionViewItemV4 opt = option;
// default alignment is centered unless specified
opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
initStyleOption(&opt, index);
painter->save();
// draw everything rotated, requires careful manipulation of the
// rects involved
painter->translate(opt.rect.bottomLeft());
painter->rotate(-90);
opt.rect = QRect(0, 0, opt.rect.height(), opt.rect.width());
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
painter->restore();
}
QSize YRegDisplayItemDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
return QSize();
}
/**
* YRegDisplay
*/
YRegDisplay::YRegDisplay(QWidget *parent)
:QAbstractItemView(parent)
{
m_is_dirty = true;
m_range_col = 0;
m_data_col = 1;
m_nr_bits = 32;
// the frame around the register is ugly, disable it
setFrameShape(QFrame::NoFrame);
setSelectionMode(SingleSelection);
setItemDelegate(new YRegDisplayItemDelegate());
}
QModelIndex RegSexyDisplay2::indexAt(const QPoint& point) const
void YRegDisplay::setWidth(int nr_bits)
{
Q_UNUSED(point);
m_nr_bits = nr_bits;
m_is_dirty = true;
recomputeGeometry();
updateGeometries();
}
int YRegDisplay::bitColumnAt(const QPoint& point, bool closest) const
{
int wx = point.x() + horizontalScrollBar()->value();
for(int bit = 0; bit < m_nr_bits; bit++)
{
int off = columnOffset(bitToColumn(bit));
int w = columnWidth(bitToColumn(bit));
if(wx >= off && wx < off + w)
return bit;
if(wx >= off + w && closest)
return bit;
}
return closest ? m_nr_bits - 1 : -1;
}
QModelIndex YRegDisplay::indexAt(const QPoint& point) const
{
if(!model())
return QModelIndex();
int wx = point.x() + horizontalScrollBar()->value();
int wy = point.y() + verticalScrollBar()->value();
for(int i = 0; i < model()->rowCount(); i++)
{
QModelIndex index = model()->index(i, m_data_col, rootIndex());
QRect r = itemRect(index);
if(!r.isValid())
continue;
if(r.contains(wx, wy))
return index;
}
return QModelIndex();
}
void RegSexyDisplay2::scrollTo(const QModelIndex& index, ScrollHint hint)
void YRegDisplay::scrollTo(const QModelIndex& index, ScrollHint hint)
{
Q_UNUSED(index);
Q_UNUSED(hint);
}
QRect RegSexyDisplay2::visualRect(const QModelIndex& index) const
QRect YRegDisplay::visualRect(const QModelIndex &index) const
{
Q_UNUSED(index);
return QRect();
QRect rect = itemRect(index);
if(rect.isValid())
return QRect(rect.left() - horizontalScrollBar()->value(),
rect.top() - verticalScrollBar()->value(),
rect.width(), rect.height());
else
return rect;
}
bool RegSexyDisplay2::isIndexHidden(const QModelIndex& index) const
bool YRegDisplay::isIndexHidden(const QModelIndex& index) const
{
Q_UNUSED(index);
return false;
}
QModelIndex RegSexyDisplay2::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
QModelIndex YRegDisplay::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(cursorAction);
Q_UNUSED(modifiers);
return QModelIndex();
}
void RegSexyDisplay2::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags)
void YRegDisplay::setSelection(const QRect& r, QItemSelectionModel::SelectionFlags flags)
{
Q_UNUSED(rect);
Q_UNUSED(flags);
if(!model())
return;
QRect rect = r.translated(horizontalScrollBar()->value(),
verticalScrollBar()->value()).normalized();
QItemSelection sel;
for(int i = 0; i < model()->rowCount(); i++)
{
QModelIndex index = model()->index(i, m_data_col, rootIndex());
QRect r = itemRect(index);
if(!r.isValid())
continue;
if(r.intersects(rect))
sel.select(index, index);
}
selectionModel()->select(sel, flags);
}
int RegSexyDisplay2::verticalOffset() const
int YRegDisplay::verticalOffset() const
{
return verticalScrollBar()->value();
}
int RegSexyDisplay2::horizontalOffset() const
int YRegDisplay::horizontalOffset() const
{
return horizontalScrollBar()->value();
}
void RegSexyDisplay2::scrollContentsBy(int dx, int dy)
void YRegDisplay::scrollContentsBy(int dx, int dy)
{
viewport()->scroll(dx, dy);
}
void RegSexyDisplay2::setModel(QAbstractItemModel *model)
void YRegDisplay::setModel(QAbstractItemModel *model)
{
QAbstractItemView::setModel(model);
m_is_dirty = true;
}
void RegSexyDisplay2::dataChanged(const QModelIndex &topLeft,
void YRegDisplay::dataChanged(const QModelIndex &topLeft,
const QModelIndex &bottomRight)
{
m_is_dirty = true;
QAbstractItemView::dataChanged(topLeft, bottomRight);
}
void RegSexyDisplay2::rowsInserted(const QModelIndex &parent, int start, int end)
void YRegDisplay::rowsInserted(const QModelIndex &parent, int start, int end)
{
m_is_dirty = true;
QAbstractItemView::rowsInserted(parent, start, end);
}
void RegSexyDisplay2::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
void YRegDisplay::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
m_is_dirty = true;
QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
}
int RegSexyDisplay2::GetSeparatorSize() const
int YRegDisplay::separatorSize() const
{
return 1;
}
int RegSexyDisplay2::GetMarginSize() const
int YRegDisplay::marginSize() const
{
return viewOptions().fontMetrics.height() / 3;
}
int RegSexyDisplay2::GetHeaderTextSep() const
int YRegDisplay::headerTextSep() const
{
return GetMarginSize() / 2;
return marginSize() / 2;
}
int RegSexyDisplay2::GetHeaderHeight() const
int YRegDisplay::headerHeight() const
{
return 2 * GetMarginSize() + GetHeaderTextSep() + 2 * viewOptions().fontMetrics.height();
return 2 * marginSize() + headerTextSep() + 2 * viewOptions().fontMetrics.height();
}
int RegSexyDisplay2::GetColumnWidth() const
int YRegDisplay::minColumnWidth() const
{
return 2 * GetMarginSize() + viewOptions().fontMetrics.height();
return 2 * marginSize() + viewOptions().fontMetrics.height();
}
int RegSexyDisplay2::GetMaxContentHeight() const
int YRegDisplay::maxColumnWidth() const
{
return 2 * minColumnWidth();
}
int YRegDisplay::columnWidth(int col) const
{
int avail = width() - (m_nr_bits + 1) * separatorSize();
int small_w = qMin(avail / m_nr_bits, maxColumnWidth());
int nr_big = avail - small_w * m_nr_bits;
if(col < nr_big)
return small_w + 1;
else
return small_w;
}
int YRegDisplay::columnOffset(int col) const
{
int off = separatorSize();
for(int i = 0; i < col; i++)
off += columnWidth(i) + separatorSize();
int all_w = off;
for(int i = col; i < m_nr_bits; i++)
all_w += columnWidth(i) + separatorSize();
return off + (width() - all_w) / 2;
}
int YRegDisplay::maxContentHeight() const
{
int max = 0;
QFontMetrics metrics = viewOptions().fontMetrics;
@ -796,127 +1009,180 @@ int RegSexyDisplay2::GetMaxContentHeight() const
{
for(int i = 0; i < model()->rowCount(); i++)
{
QModelIndex index = model()->index(i, 1, rootIndex());
QModelIndex index = model()->index(i, m_data_col, rootIndex());
QString s = model()->data(index).toString();
max = qMax(max, metrics.boundingRect(s).width());
}
}
return 2 * GetMarginSize() + max;
return 2 * marginSize() + max;
}
int RegSexyDisplay2::GetGapHeight() const
int YRegDisplay::gapHeight() const
{
return GetMarginSize() / 2;
return marginSize() / 2;
}
QRegion RegSexyDisplay2::visualRegionForSelection(const QItemSelection& selection) const
int YRegDisplay::bitToColumn(int bit) const
{
Q_UNUSED(selection);
return QRegion();
return m_nr_bits - 1 - bit;
}
void RegSexyDisplay2::paintEvent(QPaintEvent *event)
QRegion YRegDisplay::visualRegionForSelection(const QItemSelection& selection) const
{
QRegion region;
foreach(const QItemSelectionRange &range, selection)
{
for(int row = range.top(); row <= range.bottom(); ++row)
{
for(int column = range.left(); column < range.right(); ++column)
{
QModelIndex index = model()->index(row, column, rootIndex());
region += visualRect(index);
}
}
}
return region;
}
QRect YRegDisplay::itemRect(const QModelIndex& index) const
{
if(!index.isValid())
return QRect();
QVariant vrange = model()->data(model()->index(index.row(), m_range_col, rootIndex()));
if(!vrange.canConvert< SocFieldBitRange >())
return QRect();
SocFieldBitRange range = vrange.value< SocFieldBitRange >();
return itemRect(range, index.column());
}
QRect YRegDisplay::itemRect(const SocFieldBitRange& range, int col) const
{
int top, bot;
if(col == m_range_col)
{
top = separatorSize();
bot = separatorSize() + headerHeight() - 1;
}
else if(col == m_data_col)
{
top = headerHeight() + 3 * separatorSize() + gapHeight();
bot = height() - separatorSize() - 1;
}
else
return QRect();
int first_col = bitToColumn(range.GetFirstBit());
return QRect(QPoint(columnOffset(bitToColumn(range.GetLastBit())), top),
QPoint(columnOffset(first_col) + columnWidth(first_col) - 1, bot));
}
void YRegDisplay::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
int txt_h = viewOptions().fontMetrics.height();
int sep_sz = GetSeparatorSize();
int w = qMax(m_minimum_width, viewport()->width());
int h = qMax(m_minimum_height, viewport()->height());
int nr_bits = 32;
int col_w = (w - (nr_bits + 1) * sep_sz) / nr_bits;
int hdr_h = GetHeaderHeight();
int gap_h = GetGapHeight();
int tot_w = (nr_bits + 1) * sep_sz + nr_bits * col_w;
int margin = GetMarginSize();
int txt_sep = GetHeaderTextSep();
int tot_hdr_sz = 2 * sep_sz + hdr_h;
int x_shift = (w - tot_w) / 2;
#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w))
QPainter painter(viewport());
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.translate(-horizontalScrollBar()->value(), -verticalScrollBar()->value());
QStyleOptionViewItem option = viewOptions();
int txt_h = option.fontMetrics.height();
int grid_hint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);
QBrush grid_brush(static_cast< QRgb >(grid_hint));
QBrush back_brush = option.palette.base();
QBrush line_brush = option.palette.dark();
int sep_sz = separatorSize();
QItemSelectionModel *selections = selectionModel();
// fill interesting zone with base
painter.fillRect(event->rect(), option.palette.window());
painter.fillRect(x_shift, 0, tot_w, h, back_brush);
// paint header
for(int bit = 0; bit < m_nr_bits; bit++)
{
QRect r = itemRect(SocFieldBitRange(bit, bit), m_range_col);
// paint background
painter.fillRect(r, back_brush);
// paint top digit
r.setTop(r.top() + marginSize());
r.setBottom(r.top() + txt_h);
style()->drawItemText(&painter, r, Qt::AlignHCenter, option.palette,
true, QString("%1").arg(bit / 10), foregroundRole());
// paint bottom digit
r.setTop(r.bottom() + headerTextSep());
r.setBottom(r.top() + txt_h);
style()->drawItemText(&painter, r, Qt::AlignHCenter, option.palette,
true, QString("%1").arg(bit % 10), foregroundRole());
}
// paint header grid
for(int bit = 1; bit < m_nr_bits; bit++)
{
QRect r = itemRect(SocFieldBitRange(bit, bit), m_range_col);
r.setCoords(r.right() + 1, r.top(), r.right() + sep_sz, r.bottom());
if((bit % 4) == 0)
r.setCoords(r.left() - sep_sz, r.top(), r.right() + sep_sz, r.bottom());
painter.fillRect(r, grid_brush);
}
QRect hdr_r = itemRect(SocFieldBitRange(0, m_nr_bits - 1), m_range_col);
painter.fillRect(QRect(hdr_r.left(), hdr_r.top() - sep_sz, hdr_r.width(), sep_sz), grid_brush);
painter.fillRect(QRect(hdr_r.left(), hdr_r.bottom() + 1, hdr_r.width(), sep_sz), grid_brush);
// paint header gap
QRect gap_r(hdr_r.left(), hdr_r.bottom() + sep_sz + 1, hdr_r.width(), gapHeight());
painter.fillRect(gap_r, back_brush);
// paint header bottom line
painter.fillRect(QRect(gap_r.left(), gap_r.bottom() + 1, gap_r.width(), sep_sz), grid_brush);
// paint background
QRect data_r = itemRect(SocFieldBitRange(0, m_nr_bits - 1), m_data_col);
//painter.fillRect(data_r, back_brush);
// paint data bottom line
painter.fillRect(QRect(data_r.left(), data_r.bottom() + 1, data_r.width(), sep_sz), grid_brush);
// paint left/right lines
painter.fillRect(QRect(hdr_r.left() - sep_sz, hdr_r.top() - sep_sz, sep_sz, height()), grid_brush);
painter.fillRect(QRect(hdr_r.right() + 1, hdr_r.top() - sep_sz, sep_sz, height()), grid_brush);
// draw top and bottom lines
painter.setPen(QPen(line_brush, sep_sz));
painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush);
painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush);
// draw intemediate lines
for(int i = 0; i <= 32; i++)
painter.fillRect(ith_col_x(i), 0, sep_sz, 2 * sep_sz + hdr_h, line_brush);
// draw bottom header lines
painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush);
painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush);
// redraw some lines but wider
for(int i = 4; i < nr_bits; i += 4)
painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush);
// draw numbers in the header
painter.setPen(palette().brush(QPalette::ButtonText).color());
for(int i = 0; i < nr_bits; i++)
// paint model
if(!model())
return;
for(int i = 0; i < model()->rowCount(); i++)
{
QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h);
painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) / 10));
r.translate(0, txt_h + txt_sep);
painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) % 10));
QModelIndex index = model()->index(i, m_data_col, rootIndex());
QRect r = itemRect(index);
if(!r.isValid())
continue;
QString name = index.data().toString();
// paint background
QStyleOptionViewItem opt = viewOptions();
opt.rect = r;
//opt.showDecorationSelected = true;
style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, &painter, this);
if(selections->isSelected(index))
opt.state |= QStyle::State_Selected;
if(currentIndex() == index)
opt.state |= QStyle::State_HasFocus;
if(m_hover == index)
opt.state |= QStyle::State_MouseOver;
itemDelegate(index)->paint(&painter, opt, index);
// paint left/right lines
painter.fillRect(QRect(r.left() - sep_sz, r.top(), sep_sz, r.height()), grid_brush);
painter.fillRect(QRect(r.right() + 1, r.top(), sep_sz, r.height()), grid_brush);
}
// display content
if(model())
{
for(int i = 0; i < model()->rowCount(); i++)
{
QVariant vrange = model()->data(model()->index(i, 0, rootIndex()));
if(!vrange.canConvert< SocFieldBitRange >())
continue;
SocFieldBitRange range = vrange.value< SocFieldBitRange >();
QString name = model()->data(model()->index(i, 1, rootIndex())).toString();
QRect r(QPoint(ith_col_x(nr_bits - 1 - range.GetLastBit()) + sep_sz, tot_hdr_sz),
QPoint(ith_col_x(nr_bits - range.GetFirstBit()), h - sep_sz));
painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush);
painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush);
r.setY(r.y() + gap_h + sep_sz);
// draw rotated text
painter.save();
painter.translate(r.bottomLeft());
painter.rotate(-90);
//painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red));
QRect r2(0, 0, r.height(), r.width());
painter.drawText(r2, Qt::AlignCenter, name);
painter.restore();
}
}
#undef ith_col_x
}
void RegSexyDisplay2::RecomputeGeometry()
void YRegDisplay::recomputeGeometry()
{
if(!m_is_dirty)
return;
/* height: header + gap + sep + content + sep */
m_minimum_height = 0;
m_minimum_height += GetHeaderHeight() + GetGapHeight();
m_minimum_height += 2 * GetSeparatorSize() + GetMaxContentHeight();
m_minimum_height += headerHeight() + gapHeight();
m_minimum_height += 2 * separatorSize() + maxContentHeight();
/* width: sep + (col + sep) * n */
m_minimum_width = GetSeparatorSize() * 33 + GetColumnWidth() * 32;
m_minimum_width = separatorSize() * (m_nr_bits + 1) + minColumnWidth() * m_nr_bits;
m_is_dirty = false;
viewport()->update();
}
void RegSexyDisplay2::resizeEvent(QResizeEvent*)
void YRegDisplay::resizeEvent(QResizeEvent*)
{
m_is_dirty = true;
RecomputeGeometry();
recomputeGeometry();
updateGeometries();
}
void RegSexyDisplay2::updateGeometries()
void YRegDisplay::updateGeometries()
{
horizontalScrollBar()->setSingleStep(1);
horizontalScrollBar()->setPageStep(viewport()->width());
@ -926,6 +1192,35 @@ void RegSexyDisplay2::updateGeometries()
verticalScrollBar()->setRange(0, qMax(0, m_minimum_height - viewport()->height()));
}
bool YRegDisplay::viewportEvent(QEvent *event)
{
/* FIXME Apparently QAbstractItemView tracks the hovered index but keeps it
* in its private part which is not accessible, which makes it useless...
* This code reimplements it */
switch (event->type())
{
case QEvent::HoverEnter:
m_hover = indexAt(static_cast<QHoverEvent*>(event)->pos());
update(m_hover);
break;
case QEvent::HoverLeave:
update(m_hover); // update old
m_hover = QModelIndex();
break;
case QEvent::HoverMove:
{
QModelIndex old = m_hover;
m_hover = indexAt(static_cast<QHoverEvent*>(event)->pos());
if(m_hover != old)
viewport()->update(visualRect(old)|visualRect(m_hover));
break;
}
default:
break;
}
return QAbstractItemView::viewportEvent(event);
}
/**
* GrowingTableView
*/
@ -966,6 +1261,12 @@ MyTextEditor::MyTextEditor(QWidget *parent)
QVBoxLayout *layout = new QVBoxLayout;
m_toolbar = new QToolBar(this);
m_edit = new QTextEdit(this);
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
/* Qt 5.2 have a hardcoded sizeHint for QAbstractScrollArea which makes it
* hard to have a good behaviour for the text editor. Fortunately 5.2 introduces
* a new option to adjust this to the content. */
m_edit->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
#endif
layout->addWidget(m_toolbar, 0);
layout->addWidget(m_edit, 1);
setLayout(layout);
@ -1000,8 +1301,11 @@ MyTextEditor::MyTextEditor(QWidget *parent)
connect(m_edit, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)),
this, SLOT(OnCharFormatChanged(const QTextCharFormat&)));
m_edit->installEventFilter(this);
SetGrowingMode(false);
SetReadOnly(false);
m_toolbar->hide();
}
void MyTextEditor::SetReadOnly(bool en)
@ -1021,7 +1325,7 @@ void MyTextEditor::SetGrowingMode(bool en)
{
m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
m_edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
OnTextChanged();
OnInternalTextChanged();
}
else
{
@ -1036,10 +1340,11 @@ void MyTextEditor::OnInternalTextChanged()
{
int content_size = m_edit->document()->documentLayout()->documentSize().height();
content_size = qMax(content_size, m_edit->fontMetrics().height());
m_edit->setMinimumHeight(content_size + m_edit->contentsMargins().top() +
m_edit->setMinimumHeight(content_size + m_edit->contentsMargins().top() +
m_edit->contentsMargins().bottom());
}
emit OnTextChanged();
emit OnTextChanged(GetTextHtml());
}
void MyTextEditor::OnTextBold(bool checked)
@ -1094,6 +1399,19 @@ bool MyTextEditor::IsModified()
return m_edit->document()->isModified();
}
bool MyTextEditor::eventFilter(QObject *object, QEvent *event)
{
if(object != m_edit)
return false;
if(m_read_only)
return false;
if(event->type() == QEvent::FocusIn)
m_toolbar->show();
else if(event->type() == QEvent::FocusOut)
m_toolbar->hide();
return false;
}
/**
* BackendSelector
*/
@ -1159,7 +1477,10 @@ void BackendSelector::OnDataSelChanged(int index)
m_dev_selector->hide();
#endif
QFileDialog *fd = new QFileDialog(m_data_selector);
fd->setFilter("Textual files (*.txt);;All files (*)");
QStringList filters;
filters << "Textual files (*.txt)";
filters << "All files (*)";
fd->setNameFilters(filters);
fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString());
if(fd->exec())
{
@ -1251,6 +1572,47 @@ void BackendSelector::ChangeBackend(IoBackend *new_backend)
m_io_backend = new_backend;
}
/**
* YTabWidget
*/
YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent)
:QTabWidget(parent)
{
if(bar != 0)
setTabBar(bar);
m_tab_open_button = new QToolButton(this);
m_tab_open_button->setIcon(QIcon::fromTheme("list-add"));
m_tab_open_button->setAutoRaise(true);
m_tab_open_button->setPopupMode(QToolButton::InstantPopup);
/* the arrow with an icon only is pretty ugly and QToolButton has no way
* to remove the arrow programmaticaly, so use the CSS to do that */
m_tab_open_button->setStyleSheet("QToolButton::menu-indicator { image: none; }");
setCornerWidget(m_tab_open_button, Qt::TopLeftCorner);
setTabOpenable(false);
connect(m_tab_open_button, SIGNAL(clicked(bool)), this, SLOT(OnOpenButton(bool)));
/* there is a quirk in the default QStyle: if the tab bar is empty, it
* returns the minimum size of the corner widget, which is 0 for tool buttons */
//setMinimumHeight(m_tab_open_button->height());
//m_tab_open_button->setMinimumHeight(m_tab_open_button->sizeHint().height());
}
void YTabWidget::setTabOpenable(bool openable)
{
m_tab_openable = openable;
m_tab_open_button->setVisible(openable);
}
void YTabWidget::OnOpenButton(bool checked)
{
Q_UNUSED(checked);
emit tabOpenRequested();
}
void YTabWidget::setTabOpenMenu(QMenu *menu)
{
m_tab_open_button->setMenu(menu);
}
/**
* MessageWidget
*/
@ -1339,3 +1701,21 @@ void MessageWidget::OnClose(bool clicked)
Q_UNUSED(clicked);
hide();
}
/**
* Misc
*/
QGroupBox *Misc::EncloseInBox(const QString& name, QWidget *widget)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(widget);
return Misc::EncloseInBox(name, layout);
}
QGroupBox *Misc::EncloseInBox(const QString& name, QLayout *layout)
{
QGroupBox *group = new QGroupBox(name);
group->setLayout(layout);
return group;
}

View file

@ -38,9 +38,22 @@
#include <QComboBox>
#include <QFileDialog>
#include <QScrollBar>
#include <QGroupBox>
#include <QSortFilterProxyModel>
#include "settings.h"
#include "backend.h"
// FIXME see QTBUG-30392
namespace
{
template< typename T >
inline bool isUserType(const QVariant& var)
{
return var.type() == QVariant::UserType && var.userType() == qMetaTypeId< T >();
}
}
class SocBitRangeValidator : public QValidator
{
Q_OBJECT
@ -51,6 +64,13 @@ public:
virtual State validate(QString& input, int& pos) const;
/* validate and return the interpreted value */
State parse(const QString& input, int& last_bit, int& first_bit) const;
/* create a valid string from range */
QString generate(int last_bit, int first_bit) const;
/* set maximum width in bits */
void setWidth(int nr_bits);
protected:
int m_width;
};
class SocFieldValidator : public QValidator
@ -58,7 +78,7 @@ class SocFieldValidator : public QValidator
Q_OBJECT
public:
SocFieldValidator(QObject *parent = 0);
SocFieldValidator(const soc_reg_field_t& field, QObject *parent = 0);
SocFieldValidator(const soc_desc::field_t& field, QObject *parent = 0);
virtual void fixup(QString& input) const;
virtual State validate(QString& input, int& pos) const;
@ -66,7 +86,7 @@ public:
State parse(const QString& input, soc_word_t& val) const;
protected:
soc_reg_field_t m_field;
soc_desc::field_t m_field;
};
class RegLineEdit : public QWidget
@ -112,10 +132,11 @@ class SocFieldItemDelegate : public QStyledItemDelegate
{
public:
SocFieldItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent), m_bitcount(32) {}
SocFieldItemDelegate(const soc_reg_field_t& field, QObject *parent = 0)
:QStyledItemDelegate(parent), m_bitcount(field.last_bit - field.first_bit + 1) {}
SocFieldItemDelegate(const soc_desc::field_t& field, QObject *parent = 0)
:QStyledItemDelegate(parent), m_bitcount(field.width) {}
virtual QString displayText(const QVariant& value, const QLocale& locale) const;
void setWidth(int bitcount);
protected:
int m_bitcount;
};
@ -125,44 +146,54 @@ class SocFieldEditor : public QLineEdit
Q_OBJECT
Q_PROPERTY(uint field READ field WRITE setField USER true)
public:
SocFieldEditor(const soc_reg_field_t& field, QWidget *parent = 0);
SocFieldEditor(const soc_desc::field_t& field, QWidget *parent = 0);
virtual ~SocFieldEditor();
uint field() const;
void setField(uint field);
void SetRegField(const soc_reg_field_t& field);
void SetRegField(const soc_desc::field_t& field);
signals:
void editingFinished(uint value);
protected slots:
void editDone();
protected:
SocFieldValidator *m_validator;
uint m_field;
soc_reg_field_t m_reg_field;
soc_desc::field_t m_reg_field;
};
class SocFieldEditorCreator : public QItemEditorCreatorBase
{
public:
SocFieldEditorCreator() { m_field.first_bit = 0; m_field.last_bit = 31; }
SocFieldEditorCreator(const soc_reg_field_t& field):m_field(field) {}
SocFieldEditorCreator() { m_field.pos = 0; m_field.width = 32; }
SocFieldEditorCreator(const soc_desc::field_t& field):m_field(field) {}
virtual QWidget *createWidget(QWidget *parent) const;
virtual QByteArray valuePropertyName() const;
void setWidth(int bitcount);
protected:
soc_reg_field_t m_field;
soc_desc::field_t m_field;
};
class SocFieldCachedValue
{
public:
SocFieldCachedValue():m_value(0) {}
SocFieldCachedValue(const soc_reg_field_t& field, uint value);
SocFieldCachedValue(const soc_desc::field_t& field, uint value);
virtual ~SocFieldCachedValue() {}
const soc_reg_field_t& field() const { return m_field; }
const soc_desc::field_t& field() const { return m_field; }
uint value() const { return m_value; }
/* return empty string if there no match */
QString value_name() const { return m_name; }
bool operator<(const SocFieldCachedValue& o) const;
protected:
soc_reg_field_t m_field;
soc_desc::field_t m_field;
uint m_value;
QString m_name;
};
@ -172,11 +203,14 @@ Q_DECLARE_METATYPE(SocFieldCachedValue)
class SocFieldBitRange
{
public:
SocFieldBitRange():m_first_bit(0),m_last_bit(0) {}
SocFieldBitRange(const soc_reg_field_t& field)
:m_first_bit(field.first_bit), m_last_bit(field.last_bit) {}
SocFieldBitRange():m_first_bit(0), m_last_bit(0) {}
SocFieldBitRange(const soc_desc::field_t& field)
:m_first_bit(field.pos), m_last_bit(field.pos + field.width - 1) {}
SocFieldBitRange(int first, int last):m_first_bit(first), m_last_bit(last) {}
unsigned GetFirstBit() const { return m_first_bit; }
unsigned GetLastBit() const { return m_last_bit; }
bool operator<(const SocFieldBitRange& o) const;
protected:
unsigned m_first_bit, m_last_bit;
};
@ -248,14 +282,16 @@ class RegFieldTableModel : public QAbstractTableModel
Q_OBJECT
public:
RegFieldTableModel(QObject *parent);
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex & index, int role) const;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex& index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual Qt::ItemFlags flags (const QModelIndex & index) const;
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role);
void SetRegister(const soc_reg_t& reg);
void SetRegister(const soc_desc::register_t& reg);
void UpdateRegister(const soc_desc::register_t& reg);
soc_desc::register_t GetRegister() const;
/* values can either be an invalid QVariant() (means no value/error), or a
* QVariant containing a soc_word_t */
void SetValues(const QVector< QVariant >& values);
@ -286,22 +322,44 @@ protected:
Error
};
soc_reg_t m_reg;
soc_desc::register_t m_reg;
QVector< QVariant > m_value;
QVector< ColorStatus > m_status;
RegTheme m_theme;
bool m_read_only;
};
class RegSexyDisplay2 : public QAbstractItemView
class RegFieldProxyModel : public QSortFilterProxyModel
{
public:
RegFieldProxyModel(QObject *parent):QSortFilterProxyModel(parent) {}
protected:
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
};
class YRegDisplayItemDelegate : public QStyledItemDelegate
{
public:
YRegDisplayItemDelegate(QObject *parent = 0);
virtual void paint(QPainter * painter, const QStyleOptionViewItem& option,
const QModelIndex & index) const;
virtual QSize sizeHint(const QStyleOptionViewItem& option,
const QModelIndex & index) const;
};
class YRegDisplay : public QAbstractItemView
{
Q_OBJECT
public:
RegSexyDisplay2(QWidget *parent = 0);
YRegDisplay(QWidget *parent = 0);
virtual QModelIndex indexAt(const QPoint& point) const;
virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible);
virtual QRect visualRect(const QModelIndex& index ) const;
virtual QRect visualRect(const QModelIndex& index) const;
virtual void setModel(QAbstractItemModel *model);
/* specify the number of bits to display */
void setWidth(int nr_bits);
/* returns the bit column at a point, or -1 if none except if closest=true */
int bitColumnAt(const QPoint& point, bool closest = true) const;
protected slots:
virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
@ -311,14 +369,20 @@ protected slots:
virtual void updateGeometries();
protected:
int GetMarginSize() const; // margin in cells
int GetSeparatorSize() const; // size of lines betweens cells
int GetColumnWidth() const; // width of a 1-bit column (excluding separators)
int GetHeaderHeight() const; // height of the header (excluding separators)
int GetGapHeight() const; // height of gap between header and fields
int GetMaxContentHeight() const; // maximum height of field columns
int GetHeaderTextSep() const; // height between digits in header
void RecomputeGeometry();
int marginSize() const; // margin in cells
int separatorSize() const; // size of lines betweens cells
int minColumnWidth() const; // minimum width of a column (excluding separators)
int maxColumnWidth() const; // maximum width of a column (excluding separators)
int columnWidth(int col) const; // width of a 1-bit column (excluding separators)
int headerHeight() const; // height of the header (excluding separators)
int gapHeight() const; // height of gap between header and fields
int maxContentHeight() const; // maximum height of field columns
int headerTextSep() const; // height between digits in header
int columnOffset(int col) const; // column offset
int bitToColumn(int bit) const; // bit -> column
void recomputeGeometry();
QRect itemRect(const SocFieldBitRange& range, int col) const;
QRect itemRect(const QModelIndex& index) const;
virtual bool isIndexHidden(const QModelIndex& index) const;
virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
@ -328,9 +392,13 @@ protected:
virtual QRegion visualRegionForSelection(const QItemSelection& selection) const;
virtual void paintEvent(QPaintEvent *event);
virtual void resizeEvent(QResizeEvent* event);
virtual bool viewportEvent(QEvent * event);
bool m_is_dirty;
int m_minimum_width, m_minimum_height;
int m_range_col, m_data_col;
int m_nr_bits;
QModelIndex m_hover;
};
/**
@ -387,8 +455,10 @@ public:
void SetTextHtml(const QString& text);
QString GetTextHtml();
bool IsModified();
signals:
void OnTextChanged();
void OnTextChanged(const QString& text_html);
protected slots:
void OnInternalTextChanged();
@ -398,6 +468,8 @@ protected slots:
void OnCharFormatChanged(const QTextCharFormat& fmt);
protected:
virtual bool eventFilter(QObject *object, QEvent *event);
bool m_growing_mode;
bool m_read_only;
QToolBar *m_toolbar;
@ -483,4 +555,35 @@ private slots:
void OnClose(bool clicked);
};
Q_DECLARE_METATYPE(QModelIndex)
class YTabWidget : public QTabWidget
{
Q_OBJECT
Q_PROPERTY(bool tabOpenable READ tabOpenable WRITE setTabOpenable)
public:
YTabWidget(QTabBar *tabbar = 0, QWidget *parent = 0);
inline bool tabOpenable() const { return m_tab_openable; }
void setTabOpenable(bool openable);
void setTabOpenMenu(QMenu *menu);
signals:
void tabOpenRequested();
protected slots:
void OnOpenButton(bool checked);
protected:
bool m_tab_openable;
QToolButton *m_tab_open_button;
};
class Misc
{
public:
static QGroupBox *EncloseInBox(const QString& name, QWidget *widget);
static QGroupBox *EncloseInBox(const QString& name, QLayout *layout);
};
#endif /* AUX_H */