Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

regtools: add graphical register explorer + analyser

This tool allows one to explore any register map. Register dumps
(like produced by hwstub tools) can be loaded and decoded by the
tool. Finally some analysers are provided for specific soc analysis
like clock tree and emi on imx233 for example.

Change-Id: Iaf81bd52d15f3e44ab4fe9bc039153fcf60cf92a

+1792
+44
utils/regtools/qeditor/analyser.cpp
··· 1 + #include "analyser.h" 2 + 3 + Analyser::Analyser(const soc_t& soc, IoBackend *backend) 4 + :m_soc(soc), m_io_backend(backend) 5 + { 6 + } 7 + 8 + Analyser::~Analyser() 9 + { 10 + } 11 + 12 + AnalyserFactory::AnalyserFactory(bool _register) 13 + { 14 + if(_register) 15 + RegisterAnalyser(this); 16 + } 17 + 18 + AnalyserFactory::~AnalyserFactory() 19 + { 20 + } 21 + 22 + QVector< AnalyserFactory * > AnalyserFactory::m_factories; 23 + 24 + QStringList AnalyserFactory::GetAnalysersForSoc(const QString& soc_name) 25 + { 26 + QStringList list; 27 + for(int i = 0; i < m_factories.size(); i++) 28 + if(m_factories[i]->SupportSoc(soc_name)) 29 + list.append(m_factories[i]->GetName()); 30 + return list; 31 + } 32 + 33 + AnalyserFactory *AnalyserFactory::GetAnalyserByName(const QString& name) 34 + { 35 + for(int i = 0; i < m_factories.size(); i++) 36 + if(m_factories[i]->GetName() == name) 37 + return m_factories[i]; 38 + return 0; 39 + } 40 + 41 + void AnalyserFactory::RegisterAnalyser(AnalyserFactory *factory) 42 + { 43 + m_factories.append(factory); 44 + }
+64
utils/regtools/qeditor/analyser.h
··· 1 + #ifndef _ANALYSER_H_ 2 + #define _ANALYSER_H_ 3 + 4 + #include <QObject> 5 + #include <QVector> 6 + #include <QString> 7 + #include "backend.h" 8 + 9 + class Analyser : public QObject 10 + { 11 + Q_OBJECT 12 + public: 13 + Analyser(const soc_t& soc, IoBackend *backend); 14 + virtual ~Analyser(); 15 + virtual QWidget *GetWidget() = 0; 16 + 17 + protected: 18 + soc_t m_soc; 19 + IoBackend *m_io_backend; 20 + }; 21 + 22 + class AnalyserFactory 23 + { 24 + public: 25 + AnalyserFactory(bool _register); 26 + virtual ~AnalyserFactory(); 27 + 28 + virtual QString GetName() = 0; 29 + virtual bool SupportSoc(const QString& soc_name) = 0; 30 + // return NULL of soc is not handled by the analyser 31 + virtual Analyser *Create(const soc_t& soc, IoBackend *backend) = 0; 32 + private: 33 + QString m_name; 34 + 35 + public: 36 + static QStringList GetAnalysersForSoc(const QString& soc_name); 37 + static AnalyserFactory *GetAnalyserByName(const QString& name); 38 + static void RegisterAnalyser(AnalyserFactory *factory); 39 + 40 + private: 41 + static QVector< AnalyserFactory * > m_factories; 42 + }; 43 + 44 + template< typename T > 45 + class TmplAnalyserFactory : public AnalyserFactory 46 + { 47 + public: 48 + TmplAnalyserFactory(bool _register, const QString& name) :AnalyserFactory(_register) { m_name = name; } 49 + virtual ~TmplAnalyserFactory() {} 50 + 51 + virtual QString GetName() { return m_name; } 52 + virtual bool SupportSoc(const QString& soc_name) { return T::SupportSoc(soc_name); } 53 + // return NULL of soc is not handled by the analyser 54 + virtual T *Create(const soc_t& soc, IoBackend *backend) 55 + { 56 + if(!T::SupportSoc(soc.name.c_str())) 57 + return 0; 58 + return new T(soc, backend); 59 + } 60 + private: 61 + QString m_name; 62 + }; 63 + 64 + #endif /* _ANALYSER_H_ */
+156
utils/regtools/qeditor/backend.cpp
··· 1 + #include <QFile> 2 + #include <QTextStream> 3 + #include <QDebug> 4 + #include "backend.h" 5 + 6 + Backend::Backend() 7 + { 8 + } 9 + 10 + QStringList Backend::GetSocNameList() 11 + { 12 + QStringList sl; 13 + for(size_t i = 0; i < m_socs.size(); i++) 14 + sl.append(QString(m_socs[i].name.c_str())); 15 + return sl; 16 + } 17 + 18 + bool Backend::GetSocByName(const QString& name, soc_t& s) 19 + { 20 + for(size_t i = 0; i < m_socs.size(); i++) 21 + if(m_socs[i].name == name.toStdString()) 22 + { 23 + s = m_socs[i]; 24 + return true; 25 + } 26 + return false; 27 + } 28 + 29 + bool Backend::LoadSocDesc(const QString& filename) 30 + { 31 + bool ret = soc_desc_parse_xml(filename.toStdString(), m_socs); 32 + emit OnSocListChanged(); 33 + return ret; 34 + } 35 + 36 + IoBackend *Backend::CreateFileIoBackend(const QString& filename) 37 + { 38 + return new FileIoBackend(filename); 39 + } 40 + 41 + IoBackend *Backend::CreateDummyIoBackend() 42 + { 43 + return new DummyIoBackend(); 44 + } 45 + 46 + IoBackend::IoBackend() 47 + { 48 + } 49 + 50 + FileIoBackend::FileIoBackend(const QString& filename) 51 + { 52 + m_filename = filename; 53 + Reload(); 54 + } 55 + 56 + QString FileIoBackend::GetSocName() 57 + { 58 + return m_soc; 59 + } 60 + 61 + bool FileIoBackend::ReadRegister(const QString& name, soc_word_t& value) 62 + { 63 + if(m_map.find(name) == m_map.end()) 64 + return false; 65 + value = m_map[name]; 66 + return true; 67 + } 68 + 69 + bool FileIoBackend::Reload() 70 + { 71 + QFile file(m_filename); 72 + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 73 + return false; 74 + m_map.clear(); 75 + 76 + QTextStream in(&file); 77 + while(!in.atEnd()) 78 + { 79 + QString line = in.readLine(); 80 + int idx = line.indexOf('='); 81 + if(idx == -1) 82 + continue; 83 + QString key = line.left(idx).trimmed(); 84 + bool ok; 85 + soc_word_t val = line.mid(idx + 1).trimmed().toULong(&ok, 0); 86 + if(key == "HW") 87 + m_soc = line.mid(idx + 1).trimmed(); 88 + else if(ok) 89 + m_map[key] = val; 90 + } 91 + return true; 92 + } 93 + 94 + DummyIoBackend::DummyIoBackend() 95 + { 96 + } 97 + 98 + QString DummyIoBackend::GetSocName() 99 + { 100 + return ""; 101 + } 102 + 103 + bool DummyIoBackend::ReadRegister(const QString& name, soc_word_t& value) 104 + { 105 + (void) name; 106 + (void) value; 107 + return false; 108 + } 109 + 110 + bool DummyIoBackend::Reload() 111 + { 112 + return true; 113 + } 114 + 115 + BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) 116 + :m_io_backend(io_backend), m_soc(soc) 117 + { 118 + } 119 + 120 + bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) 121 + { 122 + return m_io_backend->ReadRegister("HW." + dev + "." + reg, v); 123 + } 124 + 125 + bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, 126 + const QString& field, soc_word_t& v) 127 + { 128 + soc_dev_t *sdev = 0; 129 + for(size_t i = 0; i < m_soc.dev.size(); i++) 130 + { 131 + for(size_t j = 0; j < m_soc.dev[i].addr.size(); j++) 132 + if(m_soc.dev[i].addr[j].name.c_str() == dev) 133 + sdev = &m_soc.dev[i]; 134 + } 135 + if(sdev == 0) 136 + return false; 137 + soc_reg_t *sreg = 0; 138 + for(size_t i = 0; i < sdev->reg.size(); i++) 139 + { 140 + for(size_t j = 0; j < sdev->reg[i].addr.size(); j++) 141 + if(sdev->reg[i].addr[j].name.c_str() == reg) 142 + sreg = &sdev->reg[i]; 143 + } 144 + if(sreg == 0) 145 + return false; 146 + soc_reg_field_t *sfield = 0; 147 + for(size_t i = 0; i < sreg->field.size(); i++) 148 + if(sreg->field[i].name.c_str() == field) 149 + sfield = &sreg->field[i]; 150 + if(sfield == 0) 151 + return false; 152 + if(!ReadRegister(dev, reg, v)) 153 + return false; 154 + v = (v & sfield->bitmask()) >> sfield->first_bit; 155 + return true; 156 + }
+77
utils/regtools/qeditor/backend.h
··· 1 + #ifndef __BACKEND_H__ 2 + #define __BACKEND_H__ 3 + 4 + #include <QObject> 5 + #include <QStringList> 6 + #include <QMap> 7 + #include "soc_desc.hpp" 8 + 9 + class IoBackend : public QObject 10 + { 11 + Q_OBJECT 12 + public: 13 + IoBackend(); 14 + 15 + virtual QString GetSocName() = 0; 16 + virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0; 17 + virtual bool Reload() = 0; 18 + }; 19 + 20 + class DummyIoBackend : public IoBackend 21 + { 22 + Q_OBJECT 23 + public: 24 + DummyIoBackend(); 25 + 26 + virtual QString GetSocName(); 27 + virtual bool ReadRegister(const QString& name, soc_word_t& value); 28 + virtual bool Reload(); 29 + }; 30 + 31 + class FileIoBackend : public IoBackend 32 + { 33 + Q_OBJECT 34 + public: 35 + FileIoBackend(const QString& filename); 36 + 37 + virtual QString GetSocName(); 38 + virtual bool ReadRegister(const QString& name, soc_word_t& value); 39 + virtual bool Reload(); 40 + 41 + protected: 42 + QString m_filename; 43 + QString m_soc; 44 + QMap< QString, soc_word_t > m_map; 45 + }; 46 + 47 + class Backend : public QObject 48 + { 49 + Q_OBJECT 50 + public: 51 + Backend(); 52 + 53 + QStringList GetSocNameList(); 54 + bool LoadSocDesc(const QString& filename); 55 + bool GetSocByName(const QString& name, soc_t& s); 56 + IoBackend *CreateDummyIoBackend(); 57 + IoBackend *CreateFileIoBackend(const QString& filename); 58 + 59 + signals: 60 + void OnSocListChanged(); 61 + private: 62 + std::vector< soc_t > m_socs; 63 + }; 64 + 65 + class BackendHelper 66 + { 67 + public: 68 + BackendHelper(IoBackend *io_backend, const soc_t& soc); 69 + bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v); 70 + bool ReadRegisterField(const QString& dev, const QString& reg, 71 + const QString& field, soc_word_t& v); 72 + private: 73 + IoBackend *m_io_backend; 74 + soc_t m_soc; 75 + }; 76 + 77 + #endif /* __BACKEND_H__ */
+30
utils/regtools/qeditor/main.cpp
··· 1 + #include <QApplication> 2 + #include <QDir> 3 + #include "mainwindow.h" 4 + 5 + int main(int argc, char *argv[]) 6 + { 7 + QApplication app(argc, argv); 8 + 9 + Backend *backend = new Backend; 10 + QDir dir(QCoreApplication::applicationDirPath()); 11 + dir.cdUp(); 12 + dir.cd("desc"); 13 + dir.setFilter(QDir::Files); 14 + printf("%s\n", dir.absolutePath().toStdString().c_str()); 15 + QFileInfoList list = dir.entryInfoList(); 16 + for(int i = 0; i < list.size(); i++) 17 + { 18 + QFileInfo fileInfo = list.at(i); 19 + if(fileInfo.fileName().right(4) != ".xml" || fileInfo.fileName().left(5) != "regs-") 20 + continue; 21 + backend->LoadSocDesc(fileInfo.absoluteFilePath()); 22 + } 23 + 24 + QCoreApplication::setOrganizationName("Rockbox"); 25 + QCoreApplication::setApplicationName("Register Editor"); 26 + QCoreApplication::setOrganizationDomain("rockbox.com"); 27 + MainWindow win(backend); 28 + win.show(); 29 + return app.exec(); 30 + }
+108
utils/regtools/qeditor/mainwindow.cpp
··· 1 + #include <QWidget> 2 + #include <QApplication> 3 + #include <QDesktopWidget> 4 + #include <QFileDialog> 5 + #include <QAction> 6 + #include <QMenu> 7 + #include <QMenuBar> 8 + #include <QMessageBox> 9 + #include <QTabBar> 10 + #include <QCloseEvent> 11 + #include <QDebug> 12 + 13 + #include "mainwindow.h" 14 + #include "regtab.h" 15 + 16 + MyTabWidget::MyTabWidget() 17 + { 18 + setMovable(true); 19 + setTabsClosable(true); 20 + connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(OnCloseTab(int))); 21 + } 22 + 23 + void MyTabWidget::OnCloseTab(int index) 24 + { 25 + removeTab(index); 26 + } 27 + 28 + MainWindow::MainWindow(Backend *backend) 29 + :m_backend(backend) 30 + { 31 + QAction *new_regtab_act = new QAction(QIcon::fromTheme("document-new"), tr("&Register Tab"), this); 32 + QAction *load_desc_act = new QAction(QIcon::fromTheme("document-open"), tr("&Soc Description"), this); 33 + QAction *quit_act = new QAction(QIcon::fromTheme("application-exit"), tr("&Quit"), this); 34 + QAction *about_act = new QAction(QIcon::fromTheme("help-about"), tr("&About"), this); 35 + 36 + connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab())); 37 + connect(load_desc_act, SIGNAL(triggered()), this, SLOT(OnLoadDesc())); 38 + connect(quit_act, SIGNAL(triggered()), this, SLOT(OnQuit())); 39 + connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout())); 40 + 41 + QMenu *file_menu = menuBar()->addMenu(tr("&File")); 42 + QMenu *new_submenu = file_menu->addMenu(QIcon::fromTheme("document-new"), "&New"); 43 + QMenu *load_submenu = file_menu->addMenu(QIcon::fromTheme("document-open"), "&Load"); 44 + file_menu->addAction(quit_act); 45 + 46 + new_submenu->addAction(new_regtab_act); 47 + 48 + load_submenu->addAction(load_desc_act); 49 + 50 + QMenu *about_menu = menuBar()->addMenu(tr("&About")); 51 + about_menu->addAction(about_act); 52 + 53 + m_tab = new MyTabWidget(); 54 + 55 + setCentralWidget(m_tab); 56 + 57 + ReadSettings(); 58 + } 59 + 60 + void MainWindow::ReadSettings() 61 + { 62 + restoreGeometry(Settings::Get()->value("mainwindow/geometry").toByteArray()); 63 + } 64 + 65 + void MainWindow::WriteSettings() 66 + { 67 + Settings::Get()->setValue("mainwindow/geometry", saveGeometry()); 68 + } 69 + 70 + void MainWindow::OnQuit() 71 + { 72 + WriteSettings(); 73 + } 74 + 75 + void MainWindow::OnAbout() 76 + { 77 + } 78 + 79 + void MainWindow::closeEvent(QCloseEvent *event) 80 + { 81 + WriteSettings(); 82 + event->accept(); 83 + } 84 + 85 + void MainWindow::OnLoadDesc() 86 + { 87 + QFileDialog *fd = new QFileDialog(this); 88 + fd->setFilter("XML files (*.xml);;All files (*)"); 89 + fd->setFileMode(QFileDialog::ExistingFiles); 90 + fd->setDirectory(Settings::Get()->value("mainwindow/loaddescdir", QDir::currentPath()).toString()); 91 + if(fd->exec()) 92 + { 93 + QStringList filenames = fd->selectedFiles(); 94 + for(int i = 0; i < filenames.size(); i++) 95 + if(!m_backend->LoadSocDesc(filenames[i])) 96 + { 97 + QMessageBox msg; 98 + msg.setText(QString("Cannot load ") + filenames[i]); 99 + msg.exec(); 100 + } 101 + Settings::Get()->setValue("mainwindow/loaddescdir", fd->directory().absolutePath()); 102 + } 103 + } 104 + 105 + void MainWindow::OnNewRegTab() 106 + { 107 + new RegTab(m_backend, m_tab); 108 + }
+44
utils/regtools/qeditor/mainwindow.h
··· 1 + #ifndef MAINWINDOW_H 2 + #define MAINWINDOW_H 3 + 4 + #include <QMainWindow> 5 + #include <QTabWidget> 6 + #include <QSettings> 7 + #include "backend.h" 8 + #include "settings.h" 9 + 10 + class MyTabWidget : public QTabWidget 11 + { 12 + Q_OBJECT 13 + public: 14 + MyTabWidget(); 15 + 16 + private slots: 17 + void OnCloseTab(int index); 18 + }; 19 + 20 + class MainWindow : public QMainWindow 21 + { 22 + Q_OBJECT 23 + 24 + public: 25 + MainWindow(Backend *backend); 26 + void center(); 27 + void ReadSettings(); 28 + void WriteSettings(); 29 + 30 + private: 31 + void closeEvent(QCloseEvent *event); 32 + 33 + private slots: 34 + void OnQuit(); 35 + void OnAbout(); 36 + void OnLoadDesc(); 37 + void OnNewRegTab(); 38 + 39 + private: 40 + QTabWidget *m_tab; 41 + Backend *m_backend; 42 + }; 43 + 44 + #endif
+8
utils/regtools/qeditor/qeditor.pro
··· 1 + QT += widgets 2 + 3 + HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h std_analysers.h 4 + SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp std_analysers.cpp settings.cpp 5 + LIBS += -L../lib/ -lsocdesc -lxml2 6 + INCLUDEPATH += ../lib/ 7 + 8 + CONFIG += debug
+392
utils/regtools/qeditor/regtab.cpp
··· 1 + #include "regtab.h" 2 + 3 + #include <QSplitter> 4 + #include <QVBoxLayout> 5 + #include <QGroupBox> 6 + #include <QAbstractListModel> 7 + #include <QMessageBox> 8 + #include <QSizePolicy> 9 + #include <QHBoxLayout> 10 + #include <QStringBuilder> 11 + #include <QLabel> 12 + #include <QGridLayout> 13 + #include <QTableWidget> 14 + #include <QHeaderView> 15 + #include <QFileDialog> 16 + #include "backend.h" 17 + #include "analyser.h" 18 + 19 + RegTreeItem::RegTreeItem(const QString& string, int type) 20 + :QTreeWidgetItem(QStringList(string), type) 21 + { 22 + } 23 + 24 + void RegTreeItem::SetPath(int dev_idx, int dev_addr_idx, int reg_idx, int reg_addr_idx) 25 + { 26 + m_dev_idx = dev_idx; 27 + m_dev_addr_idx = dev_addr_idx; 28 + m_reg_idx = reg_idx; 29 + m_reg_addr_idx = reg_addr_idx; 30 + } 31 + 32 + RegTab::RegTab(Backend *backend, QTabWidget *parent) 33 + :m_backend(backend) 34 + { 35 + m_splitter = new QSplitter(); 36 + QWidget *left = new QWidget; 37 + m_splitter->addWidget(left); 38 + QVBoxLayout *left_layout = new QVBoxLayout; 39 + left->setLayout(left_layout); 40 + 41 + QGroupBox *top_group = new QGroupBox("SOC selection"); 42 + QVBoxLayout *top_group_layout = new QVBoxLayout; 43 + m_soc_selector = new QComboBox; 44 + top_group_layout->addWidget(m_soc_selector); 45 + top_group->setLayout(top_group_layout); 46 + 47 + m_reg_tree = new QTreeWidget(); 48 + m_reg_tree->setColumnCount(1); 49 + m_reg_tree->setHeaderLabel(QString("Name")); 50 + 51 + m_analysers_list = new QListWidget; 52 + 53 + m_type_selector = new QTabWidget; 54 + m_type_selector->addTab(m_reg_tree, "Registers"); 55 + m_type_selector->addTab(m_analysers_list, "Analyzers"); 56 + m_type_selector->setTabPosition(QTabWidget::West); 57 + 58 + left_layout->addWidget(top_group); 59 + left_layout->addWidget(m_type_selector); 60 + 61 + m_right_panel = new QVBoxLayout; 62 + QGroupBox *data_sel_group = new QGroupBox("Data selection"); 63 + QHBoxLayout *data_sel_layout = new QHBoxLayout; 64 + m_data_selector = new QComboBox; 65 + m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing)); 66 + m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); 67 + m_data_sel_edit = new QLineEdit; 68 + m_data_sel_edit->setReadOnly(true); 69 + m_data_soc_label = new QLabel; 70 + QPushButton *data_sel_reload = new QPushButton; 71 + data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); 72 + data_sel_layout->addWidget(m_data_selector); 73 + data_sel_layout->addWidget(m_data_sel_edit); 74 + data_sel_layout->addWidget(m_data_soc_label); 75 + data_sel_layout->addWidget(data_sel_reload); 76 + data_sel_group->setLayout(data_sel_layout); 77 + m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); 78 + 79 + m_right_panel->addWidget(data_sel_group); 80 + m_right_content = new QWidget; 81 + QVBoxLayout *l = new QVBoxLayout; 82 + l->addStretch(); 83 + m_right_content->setLayout(l); 84 + m_right_panel->addWidget(m_right_content); 85 + QWidget *w = new QWidget; 86 + w->setLayout(m_right_panel); 87 + m_splitter->addWidget(w); 88 + 89 + m_io_backend = m_backend->CreateDummyIoBackend(); 90 + 91 + parent->addTab(m_splitter, "Register Tab"); 92 + 93 + connect(m_soc_selector, SIGNAL(currentIndexChanged(const QString&)), 94 + this, SLOT(OnSocChanged(const QString&))); 95 + connect(m_backend, SIGNAL(OnSocListChanged()), this, SLOT(OnSocListChanged())); 96 + connect(m_reg_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), 97 + this, SLOT(OnRegItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); 98 + connect(m_reg_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, 99 + SLOT(OnRegItemClicked(QTreeWidgetItem *, int))); 100 + connect(m_data_selector, SIGNAL(activated(int)), 101 + this, SLOT(OnDataSelChanged(int))); 102 + connect(m_data_soc_label, SIGNAL(linkActivated(const QString&)), this, 103 + SLOT(OnDataSocActivated(const QString&))); 104 + connect(m_analysers_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), 105 + this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); 106 + connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this, 107 + SLOT(OnAnalyserClicked(QListWidgetItem *))); 108 + 109 + OnSocListChanged(); 110 + OnDataSelChanged(DataSelNothing); 111 + } 112 + 113 + void RegTab::SetDataSocName(const QString& socname) 114 + { 115 + if(socname.size() != 0) 116 + { 117 + m_data_soc_label->setText("<a href=\"" + socname + "\">" + socname + "</a>"); 118 + m_data_soc_label->setTextFormat(Qt::RichText); 119 + m_data_soc_label->show(); 120 + } 121 + else 122 + { 123 + m_data_soc_label->setText(""); 124 + m_data_soc_label->hide(); 125 + } 126 + } 127 + 128 + void RegTab::OnDataSocActivated(const QString& str) 129 + { 130 + int index = m_soc_selector->findText(str); 131 + if(index != -1) 132 + m_soc_selector->setCurrentIndex(index); 133 + } 134 + 135 + void RegTab::OnDataSelChanged(int index) 136 + { 137 + if(index == -1) 138 + return; 139 + QVariant var = m_data_selector->itemData(index); 140 + if(var == DataSelFile) 141 + { 142 + QFileDialog *fd = new QFileDialog(m_data_selector); 143 + fd->setFilter("Textual files (*.txt);;All files (*)"); 144 + fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString()); 145 + if(fd->exec()) 146 + { 147 + QStringList filenames = fd->selectedFiles(); 148 + delete m_io_backend; 149 + m_io_backend = m_backend->CreateFileIoBackend(filenames[0]); 150 + m_data_sel_edit->setText(filenames[0]); 151 + SetDataSocName(m_io_backend->GetSocName()); 152 + OnDataSocActivated(m_io_backend->GetSocName()); 153 + } 154 + Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); 155 + } 156 + else 157 + { 158 + delete m_io_backend; 159 + m_io_backend = m_backend->CreateDummyIoBackend(); 160 + SetDataSocName(""); 161 + } 162 + OnDataChanged(); 163 + } 164 + 165 + void RegTab::OnDataChanged() 166 + { 167 + OnRegItemChanged(m_reg_tree->currentItem(), m_reg_tree->currentItem()); 168 + } 169 + 170 + void RegTab::OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) 171 + { 172 + (void) previous; 173 + OnRegItemClicked(current, 0); 174 + } 175 + 176 + void RegTab::OnRegItemClicked(QTreeWidgetItem *current, int col) 177 + { 178 + (void) col; 179 + if(current == 0) 180 + return; 181 + RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); 182 + if(item->type() != RegTreeRegType) 183 + return; 184 + soc_dev_t& dev = m_cur_soc.dev[item->GetDevIndex()]; 185 + soc_dev_addr_t& dev_addr = dev.addr[item->GetDevAddrIndex()]; 186 + soc_reg_t& reg = dev.reg[item->GetRegIndex()]; 187 + soc_reg_addr_t& reg_addr = reg.addr[item->GetRegAddrIndex()]; 188 + 189 + DisplayRegister(dev, dev_addr, reg, reg_addr); 190 + } 191 + 192 + void RegTab::OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous) 193 + { 194 + (void) previous; 195 + OnAnalyserClicked(current); 196 + } 197 + 198 + void RegTab::OnAnalyserClicked(QListWidgetItem *current) 199 + { 200 + if(current == 0) 201 + return; 202 + delete m_right_content; 203 + AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); 204 + m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget(); 205 + m_right_panel->addWidget(m_right_content); 206 + } 207 + 208 + void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, 209 + soc_reg_t& reg, soc_reg_addr_t& reg_addr) 210 + { 211 + (void) dev; 212 + delete m_right_content; 213 + 214 + QVBoxLayout *right_layout = new QVBoxLayout; 215 + 216 + QString reg_name; 217 + reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str()); 218 + QStringList names; 219 + QVector< soc_addr_t > addresses; 220 + names.append(reg_name); 221 + addresses.append(reg_addr.addr); 222 + if(reg.flags & REG_HAS_SCT) 223 + { 224 + names.append(reg_name + "_SET"); 225 + names.append(reg_name + "_CLR"); 226 + names.append(reg_name + "_TOG"); 227 + addresses.append(reg_addr.addr + 4); 228 + addresses.append(reg_addr.addr + 8); 229 + addresses.append(reg_addr.addr + 12); 230 + } 231 + 232 + QString str; 233 + str += "<table align=left>"; 234 + for(int i = 0; i < names.size(); i++) 235 + str += "<tr><td><b>" + names[i] + "</b></td></tr>"; 236 + str += "</table>"; 237 + QLabel *label_names = new QLabel; 238 + label_names->setTextFormat(Qt::RichText); 239 + label_names->setText(str); 240 + 241 + QString str_addr; 242 + str_addr += "<table align=left>"; 243 + for(int i = 0; i < names.size(); i++) 244 + str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>"; 245 + str_addr += "</table>"; 246 + QLabel *label_addr = new QLabel; 247 + label_addr->setTextFormat(Qt::RichText); 248 + label_addr->setText(str_addr); 249 + 250 + QHBoxLayout *top_layout = new QHBoxLayout; 251 + top_layout->addStretch(); 252 + top_layout->addWidget(label_names); 253 + top_layout->addWidget(label_addr); 254 + top_layout->addStretch(); 255 + 256 + soc_word_t value; 257 + bool has_value = m_io_backend->ReadRegister(QString().sprintf("HW.%s.%s", 258 + dev_addr.name.c_str(), reg_addr.name.c_str()), value); 259 + 260 + QHBoxLayout *raw_val_layout = 0; 261 + if(has_value) 262 + { 263 + QLabel *raw_val_name = new QLabel; 264 + raw_val_name->setText("Raw value:"); 265 + QLineEdit *raw_val_edit = new QLineEdit; 266 + raw_val_edit->setReadOnly(true); 267 + raw_val_edit->setText(QString().sprintf("0x%08x", value)); 268 + raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 269 + raw_val_layout = new QHBoxLayout; 270 + raw_val_layout->addStretch(); 271 + raw_val_layout->addWidget(raw_val_name); 272 + raw_val_layout->addWidget(raw_val_edit); 273 + raw_val_layout->addStretch(); 274 + } 275 + 276 + QTableWidget *value_table = new QTableWidget; 277 + value_table->setRowCount(reg.field.size()); 278 + value_table->setColumnCount(4); 279 + for(size_t i = 0; i < reg.field.size(); i++) 280 + { 281 + QString bits_str; 282 + if(reg.field[i].first_bit == reg.field[i].last_bit) 283 + bits_str.sprintf("%d", reg.field[i].first_bit); 284 + else 285 + bits_str.sprintf("%d:%d", reg.field[i].last_bit, reg.field[i].first_bit); 286 + QTableWidgetItem *item = new QTableWidgetItem(bits_str); 287 + item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); 288 + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 289 + value_table->setItem(i, 0, item); 290 + item = new QTableWidgetItem(QString(reg.field[i].name.c_str())); 291 + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 292 + value_table->setItem(i, 1, item); 293 + item = new QTableWidgetItem(); 294 + if(has_value) 295 + { 296 + const soc_reg_field_t& field = reg.field[i]; 297 + soc_word_t v = (value & field.bitmask()) >> field.first_bit; 298 + QString value_name; 299 + for(size_t j = 0; j < field.value.size(); j++) 300 + if(v == field.value[j].value) 301 + value_name = field.value[j].name.c_str(); 302 + const char *fmt = "%lu"; 303 + // heuristic 304 + if((field.last_bit - field.first_bit + 1) > 16) 305 + fmt = "0x%lx"; 306 + item->setText(QString().sprintf(fmt, (unsigned long)v)); 307 + item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); 308 + 309 + if(value_name.size() != 0) 310 + { 311 + QTableWidgetItem *t = new QTableWidgetItem(value_name); 312 + t->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); 313 + t->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 314 + value_table->setItem(i, 3, t); 315 + } 316 + } 317 + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 318 + value_table->setItem(i, 2, item); 319 + } 320 + value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits")); 321 + value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); 322 + value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); 323 + value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning")); 324 + value_table->verticalHeader()->setVisible(false); 325 + value_table->resizeColumnsToContents(); 326 + value_table->horizontalHeader()->setStretchLastSection(true); 327 + value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 328 + 329 + right_layout->addLayout(top_layout); 330 + if(raw_val_layout) 331 + right_layout->addLayout(raw_val_layout); 332 + //right_layout->addWidget(bits_label); 333 + right_layout->addWidget(value_table); 334 + //right_layout->addStretch(); 335 + 336 + m_right_content = new QGroupBox("Register Description"); 337 + m_right_content->setLayout(right_layout); 338 + m_right_panel->addWidget(m_right_content); 339 + } 340 + 341 + void RegTab::OnSocListChanged() 342 + { 343 + m_soc_selector->clear(); 344 + QStringList socs = m_backend->GetSocNameList(); 345 + for(int i = 0; i < socs.size(); i++) 346 + m_soc_selector->addItem(socs[i]); 347 + } 348 + 349 + void RegTab::FillDevSubTree(RegTreeItem *item) 350 + { 351 + soc_dev_t& sd = m_cur_soc.dev[item->GetDevIndex()]; 352 + for(size_t i = 0; i < sd.reg.size(); i++) 353 + { 354 + soc_reg_t& reg = sd.reg[i]; 355 + for(size_t j = 0; j < reg.addr.size(); j++) 356 + { 357 + RegTreeItem *reg_item = new RegTreeItem(reg.addr[j].name.c_str(), RegTreeRegType); 358 + reg_item->SetPath(item->GetDevIndex(), item->GetDevAddrIndex(), i, j); 359 + item->addChild(reg_item); 360 + } 361 + } 362 + } 363 + 364 + void RegTab::FillRegTree() 365 + { 366 + for(size_t i = 0; i < m_cur_soc.dev.size(); i++) 367 + { 368 + soc_dev_t& sd = m_cur_soc.dev[i]; 369 + for(size_t j = 0; j < sd.addr.size(); j++) 370 + { 371 + RegTreeItem *dev_item = new RegTreeItem(sd.addr[j].name.c_str(), RegTreeDevType); 372 + dev_item->SetPath(i, j); 373 + FillDevSubTree(dev_item); 374 + m_reg_tree->addTopLevelItem(dev_item); 375 + } 376 + } 377 + } 378 + 379 + void RegTab::FillAnalyserList() 380 + { 381 + m_analysers_list->clear(); 382 + m_analysers_list->addItems(AnalyserFactory::GetAnalysersForSoc(m_cur_soc.name.c_str())); 383 + } 384 + 385 + void RegTab::OnSocChanged(const QString& soc) 386 + { 387 + m_reg_tree->clear(); 388 + if(!m_backend->GetSocByName(soc, m_cur_soc)) 389 + return; 390 + FillRegTree(); 391 + FillAnalyserList(); 392 + }
+85
utils/regtools/qeditor/regtab.h
··· 1 + #ifndef REGTAB_H 2 + #define REGTAB_H 3 + 4 + #include <QComboBox> 5 + #include <QEvent> 6 + #include <QTreeWidget> 7 + #include <QVBoxLayout> 8 + #include <QTabWidget> 9 + #include <QSplitter> 10 + #include <QLineEdit> 11 + #include <QPushButton> 12 + #include <QLabel> 13 + #include <QListWidget> 14 + #include <soc_desc.hpp> 15 + #include "backend.h" 16 + #include "settings.h" 17 + 18 + enum 19 + { 20 + RegTreeDevType = QTreeWidgetItem::UserType, 21 + RegTreeRegType 22 + }; 23 + 24 + enum 25 + { 26 + DataSelNothing, 27 + DataSelFile, 28 + }; 29 + 30 + class RegTreeItem : public QTreeWidgetItem 31 + { 32 + public: 33 + RegTreeItem(const QString& string, int type); 34 + 35 + void SetPath(int dev_idx, int dev_addr_idx, int reg_idx = -1, int reg_addr_idx = -1); 36 + int GetDevIndex() const { return m_dev_idx; } 37 + int GetDevAddrIndex() const { return m_dev_addr_idx; } 38 + int GetRegIndex() const { return m_reg_idx; } 39 + int GetRegAddrIndex() const { return m_reg_addr_idx; } 40 + private: 41 + int m_dev_idx, m_dev_addr_idx, m_reg_idx, m_reg_addr_idx; 42 + }; 43 + 44 + class RegTab : public QObject 45 + { 46 + Q_OBJECT 47 + public: 48 + RegTab(Backend *backend, QTabWidget *parent); 49 + 50 + protected: 51 + void FillDevSubTree(RegTreeItem *item); 52 + void FillRegTree(); 53 + void FillAnalyserList(); 54 + void UpdateSocList(); 55 + void DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, 56 + soc_reg_t& reg, soc_reg_addr_t& reg_addr); 57 + void SetDataSocName(const QString& socname); 58 + QComboBox *m_soc_selector; 59 + Backend *m_backend; 60 + QTreeWidget *m_reg_tree; 61 + soc_t m_cur_soc; 62 + QVBoxLayout *m_right_panel; 63 + QWidget *m_right_content; 64 + QSplitter *m_splitter; 65 + QLineEdit *m_data_sel_edit; 66 + QLabel *m_data_soc_label; 67 + QPushButton *m_data_sel_reload; 68 + QComboBox *m_data_selector; 69 + IoBackend *m_io_backend; 70 + QTabWidget *m_type_selector; 71 + QListWidget *m_analysers_list; 72 + 73 + private slots: 74 + void OnSocChanged(const QString& text); 75 + void OnSocListChanged(); 76 + void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); 77 + void OnRegItemClicked(QTreeWidgetItem *clicked, int col); 78 + void OnDataSelChanged(int index); 79 + void OnDataChanged(); 80 + void OnDataSocActivated(const QString&); 81 + void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); 82 + void OnAnalyserClicked(QListWidgetItem *clicked); 83 + }; 84 + 85 + #endif /* REGTAB_H */
+32
utils/regtools/qeditor/settings.cpp
··· 1 + #include <QCoreApplication> 2 + #include <QDebug> 3 + #include "settings.h" 4 + 5 + Settings::Settings() 6 + { 7 + 8 + } 9 + 10 + Settings::~Settings() 11 + { 12 + if(m_settings) 13 + delete m_settings; 14 + } 15 + 16 + QSettings *Settings::GetSettings() 17 + { 18 + if(!m_settings) 19 + { 20 + QDir dir(QCoreApplication::applicationDirPath()); 21 + QString filename = dir.filePath(QCoreApplication::organizationDomain() + ".ini"); 22 + m_settings = new QSettings(filename, QSettings::IniFormat); 23 + } 24 + return m_settings; 25 + } 26 + 27 + QSettings *Settings::Get() 28 + { 29 + return g_settings.GetSettings(); 30 + } 31 + 32 + Settings Settings::g_settings;
+21
utils/regtools/qeditor/settings.h
··· 1 + #ifndef _SETTINGS_H_ 2 + #define _SETTINGS_H_ 3 + 4 + #include <QSettings> 5 + #include <QString> 6 + #include <QDir> 7 + 8 + class Settings 9 + { 10 + public: 11 + Settings(); 12 + ~Settings(); 13 + 14 + QSettings *GetSettings(); 15 + static QSettings *Get(); 16 + private: 17 + QSettings *m_settings; 18 + static Settings g_settings; 19 + }; 20 + 21 + #endif /* _SETTINGS_H_ */
+636
utils/regtools/qeditor/std_analysers.cpp
··· 1 + #include "std_analysers.h" 2 + 3 + /** 4 + * Clock analyser 5 + */ 6 + 7 + ClockAnalyser::ClockAnalyser(const soc_t& soc, IoBackend *backend) 8 + :Analyser(soc, backend) 9 + { 10 + m_group = new QGroupBox("Clock Analyser"); 11 + QVBoxLayout *layout = new QVBoxLayout; 12 + m_group->setLayout(layout); 13 + m_tree_widget = new QTreeWidget; 14 + layout->addWidget(m_tree_widget); 15 + 16 + m_tree_widget->setColumnCount(2); 17 + QStringList list; 18 + list << "Name" << "Frequency"; 19 + m_tree_widget->setHeaderLabels(list); 20 + 21 + FillTree(); 22 + } 23 + 24 + ClockAnalyser::~ClockAnalyser() 25 + { 26 + } 27 + 28 + QWidget *ClockAnalyser::GetWidget() 29 + { 30 + return m_group; 31 + } 32 + 33 + bool ClockAnalyser::SupportSoc(const QString& soc_name) 34 + { 35 + return soc_name == "imx233"; 36 + } 37 + 38 + QString ClockAnalyser::GetFreq(unsigned freq) 39 + { 40 + if(freq >= 1000000) 41 + { 42 + if((freq % 1000000) == 0) 43 + return QString().sprintf("%d MHz", freq / 1000000); 44 + else 45 + return QString().sprintf("%.3f MHz", freq / 1000000.0); 46 + } 47 + if(freq >= 1000) 48 + { 49 + if((freq % 1000) == 0) 50 + return QString().sprintf("%d KHz", freq / 1000); 51 + else 52 + return QString().sprintf("%.3f KHz", freq / 1000.0); 53 + } 54 + return QString().sprintf("%d Hz", freq); 55 + } 56 + 57 + QTreeWidgetItem *ClockAnalyser::AddClock(QTreeWidgetItem *parent, const QString& name, int freq, int mul, int div) 58 + { 59 + if(freq == FROM_PARENT) 60 + { 61 + int64_t f = GetClockFreq(parent); 62 + f *= mul; 63 + f /= div; 64 + freq = f; 65 + } 66 + QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList() << name 67 + << (freq == INVALID ? "<invalid>" : freq == 0 ? "<disabled>" : GetFreq(freq))); 68 + item->setData(1, Qt::UserRole, freq); 69 + if(freq == DISABLED || freq == INVALID || (parent && parent->isDisabled())) 70 + item->setDisabled(true); 71 + if(!parent) 72 + m_tree_widget->addTopLevelItem(item); 73 + return item; 74 + } 75 + 76 + int ClockAnalyser::GetClockFreq(QTreeWidgetItem *item) 77 + { 78 + return item->data(1, Qt::UserRole).toInt(); 79 + } 80 + 81 + void ClockAnalyser::FillTree() 82 + { 83 + m_tree_widget->clear(); 84 + BackendHelper helper(m_io_backend, m_soc); 85 + soc_word_t value, value2, value3; 86 + 87 + QTreeWidgetItem *ring_osc = 0; 88 + if(helper.ReadRegisterField("POWER", "MINPWR", "ENABLE_OSC", value)) 89 + ring_osc = AddClock(0, "ring_clk24m", value ? 24000000 : DISABLED); 90 + else 91 + ring_osc = AddClock(0, "ring_clk24m", INVALID); 92 + QTreeWidgetItem *xtal_osc = 0; 93 + if(helper.ReadRegisterField("POWER", "MINPWR", "PWD_XTAL24", value)) 94 + xtal_osc = AddClock(0, "xtal_clk24m", value ? DISABLED : 24000000); 95 + else 96 + xtal_osc = AddClock(0, "xtal_clk24m", INVALID); 97 + QTreeWidgetItem *ref_xtal = 0; 98 + if(helper.ReadRegisterField("POWER", "MINPWR", "SELECT_OSC", value)) 99 + ref_xtal = AddClock(value ? ring_osc : xtal_osc, "ref_xtal", FROM_PARENT); 100 + else 101 + ref_xtal = AddClock(0, "ref_xtal", INVALID); 102 + 103 + QTreeWidgetItem *ref_pll = 0; 104 + if(helper.ReadRegisterField("CLKCTRL", "PLLCTRL0", "POWER", value)) 105 + ref_pll = AddClock(ref_xtal, "ref_pll", FROM_PARENT, 20); 106 + else 107 + ref_pll = AddClock(0, "ref_pll", INVALID); 108 + 109 + QTreeWidgetItem *ref_io = 0; 110 + if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEIO", value) && 111 + helper.ReadRegisterField("CLKCTRL", "FRAC", "IOFRAC", value2)) 112 + ref_io = AddClock(ref_pll, "ref_io", value ? DISABLED : FROM_PARENT, 18, value2); 113 + else 114 + ref_io = AddClock(ref_pll, "ref_io", INVALID); 115 + 116 + QTreeWidgetItem *ref_pix = 0; 117 + if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEPIX", value) && 118 + helper.ReadRegisterField("CLKCTRL", "FRAC", "PIXFRAC", value2)) 119 + ref_pix = AddClock(ref_pll, "ref_pix", value ? DISABLED : FROM_PARENT, 18, value2); 120 + else 121 + ref_pix = AddClock(ref_pll, "ref_pix", INVALID); 122 + 123 + QTreeWidgetItem *ref_emi = 0; 124 + if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATEEMI", value) && 125 + helper.ReadRegisterField("CLKCTRL", "FRAC", "EMIFRAC", value2)) 126 + ref_emi = AddClock(ref_pll, "ref_emi", value ? DISABLED : FROM_PARENT, 18, value2); 127 + else 128 + ref_emi = AddClock(ref_pll, "ref_emi", INVALID); 129 + 130 + QTreeWidgetItem *ref_cpu = 0; 131 + if(helper.ReadRegisterField("CLKCTRL", "FRAC", "CLKGATECPU", value) && 132 + helper.ReadRegisterField("CLKCTRL", "FRAC", "CPUFRAC", value2)) 133 + ref_cpu = AddClock(ref_pll, "ref_cpu", value ? DISABLED : FROM_PARENT, 18, value2); 134 + else 135 + ref_cpu = AddClock(ref_pll, "ref_cpu", INVALID); 136 + 137 + QTreeWidgetItem *clk_p = 0; 138 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_CPU", value)) 139 + { 140 + if(!value) 141 + { 142 + if(helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_CPU", value2)) 143 + clk_p = AddClock(ref_cpu, "clk_p", FROM_PARENT, 1, value2); 144 + else 145 + clk_p = AddClock(ref_cpu, "clk_p", INVALID); 146 + } 147 + else 148 + { 149 + if(helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_XTAL_FRAC_EN", value) && 150 + helper.ReadRegisterField("CLKCTRL", "CPU", "DIV_XTAL", value2)) 151 + clk_p = AddClock(ref_xtal, "clk_p", FROM_PARENT, value ? 1024 : 1, value2); 152 + else 153 + clk_p = AddClock(ref_xtal, "clk_p", INVALID); 154 + } 155 + } 156 + else 157 + clk_p = AddClock(ref_xtal, "clk_p", INVALID); 158 + 159 + QTreeWidgetItem *clk_h = 0; 160 + if(helper.ReadRegisterField("CLKCTRL", "HBUS", "DIV_FRAC_EN", value) && 161 + helper.ReadRegisterField("CLKCTRL", "HBUS", "DIV", value2)) 162 + clk_h = AddClock(clk_p, "clk_h", FROM_PARENT, value ? 32 : 1, value2); 163 + else 164 + clk_h = AddClock(clk_p, "clk_h", INVALID); 165 + 166 + QTreeWidgetItem *clk_x = 0; 167 + if(helper.ReadRegisterField("CLKCTRL", "XBUS", "DIV", value)) 168 + clk_x = AddClock(ref_xtal, "clk_x", FROM_PARENT, 1, value); 169 + else 170 + clk_x = AddClock(ref_xtal, "clk_x", INVALID); 171 + 172 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "UART_CLK_GATE", value)) 173 + AddClock(ref_xtal, "clk_uart", value ? DISABLED : FROM_PARENT); 174 + else 175 + AddClock(ref_xtal, "clk_uart", INVALID); 176 + 177 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "FILT_CLK24M_GATE", value)) 178 + AddClock(ref_xtal, "clk_filt24m", value ? DISABLED : FROM_PARENT); 179 + else 180 + AddClock(ref_xtal, "clk_filt24m", INVALID); 181 + 182 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "PWM_CLK24M_GATE", value)) 183 + AddClock(ref_xtal, "clk_pwm24m", value ? DISABLED : FROM_PARENT); 184 + else 185 + AddClock(ref_xtal, "clk_pwm24m", INVALID); 186 + 187 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "DRI_CLK24M_GATE", value)) 188 + AddClock(ref_xtal, "clk_dri24m", value ? DISABLED : FROM_PARENT); 189 + else 190 + AddClock(ref_xtal, "clk_dri24m", INVALID); 191 + 192 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "DIGCTRL_CLK1M_GATE", value)) 193 + AddClock(ref_xtal, "clk_1m", value ? DISABLED : FROM_PARENT, 1, 24); 194 + else 195 + AddClock(ref_xtal, "clk_1m", INVALID); 196 + 197 + QTreeWidgetItem *clk_32k = 0; 198 + if(helper.ReadRegisterField("CLKCTRL", "XTAL", "TIMROT_CLK32K_GATE", value)) 199 + clk_32k = AddClock(ref_xtal, "clk_32k", value ? DISABLED : FROM_PARENT, 1, 750); 200 + else 201 + clk_32k = AddClock(ref_xtal, "clk_32k", INVALID); 202 + 203 + AddClock(clk_32k, "clk_adc", FROM_PARENT, 1, 16); 204 + 205 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_PIX", value) && 206 + helper.ReadRegisterField("CLKCTRL", "PIX", "DIV", value2)) 207 + AddClock(value ? ref_xtal : ref_pix, "clk_pix", FROM_PARENT, 1, value2); 208 + else 209 + AddClock(ref_xtal, "clk_p", INVALID); 210 + 211 + QTreeWidgetItem *clk_ssp = 0; 212 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_SSP", value) && 213 + helper.ReadRegisterField("CLKCTRL", "SSP", "DIV", value2) && 214 + helper.ReadRegisterField("CLKCTRL", "SSP", "CLKGATE", value3)) 215 + clk_ssp = AddClock(value ? ref_xtal : ref_io, "clk_ssp", value3 ? DISABLED : FROM_PARENT, 1, value2); 216 + else 217 + clk_ssp = AddClock(ref_xtal, "clk_p", INVALID); 218 + 219 + if(helper.ReadRegisterField("SSP1", "TIMING", "CLOCK_DIVIDE", value) && 220 + helper.ReadRegisterField("SSP1", "TIMING", "CLOCK_RATE", value2) && 221 + helper.ReadRegisterField("SSP1", "CTRL0", "CLKGATE", value3)) 222 + AddClock(clk_ssp, "clk_ssp1", value3 ? DISABLED : FROM_PARENT, 1, value * (1 + value2)); 223 + else 224 + AddClock(clk_ssp, "clk_ssp1", INVALID); 225 + 226 + if(helper.ReadRegisterField("SSP2", "TIMING", "CLOCK_DIVIDE", value) && 227 + helper.ReadRegisterField("SSP2", "TIMING", "CLOCK_RATE", value2) && 228 + helper.ReadRegisterField("SSP2", "CTRL0", "CLKGATE", value3)) 229 + AddClock(clk_ssp, "clk_ssp2", value3 ? DISABLED : FROM_PARENT, 1, value * (1 + value2)); 230 + else 231 + AddClock(clk_ssp, "clk_ssp2", INVALID); 232 + 233 + QTreeWidgetItem *clk_gpmi = 0; 234 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_GPMI", value) && 235 + helper.ReadRegisterField("CLKCTRL", "GPMI", "DIV", value2) && 236 + helper.ReadRegisterField("CLKCTRL", "GPMI", "CLKGATE", value3)) 237 + clk_gpmi = AddClock(value ? ref_xtal : ref_io, "clk_gpmi", value3 ? DISABLED : FROM_PARENT, 1, value2); 238 + else 239 + clk_gpmi = AddClock(ref_xtal, "clk_p", INVALID); 240 + 241 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value)) 242 + { 243 + if(!value) 244 + { 245 + if(helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_EMI", value2) && 246 + helper.ReadRegisterField("CLKCTRL", "EMI", "CLKGATE", value3)) 247 + AddClock(ref_emi, "clk_emi", value3 ? DISABLED : FROM_PARENT, 1, value2); 248 + else 249 + AddClock(ref_emi, "clk_emi", INVALID); 250 + } 251 + else 252 + { 253 + if(helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_XTAL", value2) && 254 + helper.ReadRegisterField("CLKCTRL", "EMI", "CLKGATE", value3)) 255 + AddClock(ref_xtal, "clk_emi", value3 ? DISABLED : FROM_PARENT, 1, value2); 256 + else 257 + AddClock(ref_xtal, "clk_emi", INVALID); 258 + } 259 + } 260 + else 261 + clk_p = AddClock(ref_xtal, "clk_emi", INVALID); 262 + 263 + QTreeWidgetItem *ref_vid = AddClock(ref_pll, "clk_vid", FROM_PARENT); 264 + 265 + if(helper.ReadRegisterField("CLKCTRL", "TV", "CLK_TV108M_GATE", value) && 266 + helper.ReadRegisterField("CLKCTRL", "TV", "CLK_TV_GATE", value2)) 267 + { 268 + QTreeWidgetItem *clk_tv108m = AddClock(ref_vid, "clk_tv108m", value ? DISABLED : FROM_PARENT, 1, 4); 269 + AddClock(clk_tv108m, "clk_tv54m", value2 ? DISABLED : FROM_PARENT, 1, 2); 270 + AddClock(clk_tv108m, "clk_tv27m", value2 ? DISABLED : FROM_PARENT, 1, 4); 271 + } 272 + 273 + if(helper.ReadRegisterField("CLKCTRL", "PLLCTRL0", "EN_USB_CLKS", value)) 274 + AddClock(ref_pll, "utmi_clk480m", value ? FROM_PARENT : DISABLED); 275 + else 276 + AddClock(ref_pll, "utmi_clk480m", INVALID); 277 + 278 + QTreeWidgetItem *xtal_clk32k = 0; 279 + if(helper.ReadRegisterField("RTC", "PERSISTENT0", "XTAL32_FREQ", value) && 280 + helper.ReadRegisterField("RTC", "PERSISTENT0", "XTAL32KHZ_PWRUP", value2)) 281 + xtal_clk32k = AddClock(0, "xtal_clk32k", value2 == 0 ? DISABLED : value ? 32000 : 32768); 282 + else 283 + xtal_clk32k = AddClock(0, "xtal_clk32k", INVALID); 284 + 285 + if(helper.ReadRegisterField("RTC", "PERSISTENT0", "CLOCKSOURCE", value)) 286 + AddClock(value ? xtal_clk32k : ref_xtal, "clk_rtc32k", FROM_PARENT, 1, value ? 1 : 768); 287 + else 288 + AddClock(ref_xtal, "clk_rtc32k", INVALID); 289 + 290 + (void) clk_x; 291 + (void) clk_gpmi; 292 + (void) clk_h; 293 + 294 + m_tree_widget->expandAll(); 295 + m_tree_widget->resizeColumnToContents(0); 296 + } 297 + 298 + static TmplAnalyserFactory< ClockAnalyser > g_clock_factory(true, "Clock Analyser"); 299 + 300 + /** 301 + * EMI analyser 302 + */ 303 + EmiAnalyser::EmiAnalyser(const soc_t& soc, IoBackend *backend) 304 + :Analyser(soc, backend) 305 + { 306 + m_group = new QGroupBox("EMI Analyser"); 307 + QVBoxLayout *layout = new QVBoxLayout; 308 + m_group->setLayout(layout); 309 + m_panel = new QToolBox; 310 + m_display_selector = new QComboBox; 311 + m_display_selector->addItem("Cycles", DisplayCycles); 312 + m_display_selector->addItem("Raw Hexadecimal", DisplayRawHex); 313 + m_display_selector->addItem("Time", DisplayTime); 314 + QHBoxLayout *line_layout = new QHBoxLayout; 315 + line_layout->addWidget(new QLabel("Display Mode:")); 316 + line_layout->addWidget(m_display_selector); 317 + m_emi_freq_label = new QLineEdit; 318 + m_emi_freq_label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 319 + m_emi_freq_label->setReadOnly(true); 320 + line_layout->addStretch(); 321 + line_layout->addWidget(new QLabel("Frequency:")); 322 + line_layout->addWidget(m_emi_freq_label); 323 + line_layout->addWidget(new QLabel("MHz")); 324 + line_layout->addStretch(); 325 + layout->addLayout(line_layout); 326 + layout->addWidget(m_panel); 327 + 328 + connect(m_display_selector, SIGNAL(currentIndexChanged(int)), this, 329 + SLOT(OnChangeDisplayMode(int))); 330 + 331 + FillTable(); 332 + } 333 + 334 + EmiAnalyser::~EmiAnalyser() 335 + { 336 + } 337 + 338 + QWidget *EmiAnalyser::GetWidget() 339 + { 340 + return m_group; 341 + } 342 + 343 + bool EmiAnalyser::SupportSoc(const QString& soc_name) 344 + { 345 + return soc_name == "imx233"; 346 + } 347 + 348 + void EmiAnalyser::OnChangeDisplayMode(int index) 349 + { 350 + m_display_mode = (DisplayMode)m_display_selector->itemData(index).toInt(); 351 + int idx = m_panel->currentIndex(); 352 + FillTable(); 353 + m_panel->setCurrentIndex(idx); 354 + } 355 + 356 + void EmiAnalyser::NewGroup(const QString& name) 357 + { 358 + QTableWidget *table = new QTableWidget; 359 + table->setColumnCount(3); 360 + table->setHorizontalHeaderItem(0, new QTableWidgetItem("Name")); 361 + table->setHorizontalHeaderItem(1, new QTableWidgetItem("Value")); 362 + table->setHorizontalHeaderItem(2, new QTableWidgetItem("Comment")); 363 + table->verticalHeader()->setVisible(false); 364 + table->horizontalHeader()->setStretchLastSection(true); 365 + m_panel->addItem(table, name); 366 + } 367 + 368 + void EmiAnalyser::AddLine(const QString& name, int value, const QString& unit, const QString& comment) 369 + { 370 + QTableWidget *table = dynamic_cast< QTableWidget* >(m_panel->widget(m_panel->count() - 1)); 371 + int row = table->rowCount(); 372 + table->setRowCount(row + 1); 373 + table->setItem(row, 0, new QTableWidgetItem(name)); 374 + QString val; 375 + if(value == INVALID) 376 + val = "<invalid>"; 377 + else if(value == NONE) 378 + val = unit; 379 + else if(m_display_mode == DisplayRawHex && unit.size() == 0) 380 + val = QString("0x%1").arg(value, 0, 16); 381 + else 382 + val = QString("%1%2").arg(value).arg(unit); 383 + table->setItem(row, 1, new QTableWidgetItem(val)); 384 + table->item(row, 1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 385 + table->setItem(row, 2, new QTableWidgetItem(comment)); 386 + table->resizeColumnToContents(0); 387 + table->resizeColumnToContents(1); 388 + } 389 + 390 + void EmiAnalyser::AddCycleLine(const QString& name, unsigned raw_val, float val, 391 + int digits, const QString& comment) 392 + { 393 + if(m_display_mode == DisplayCycles) 394 + { 395 + QString str; 396 + if(digits == 0) 397 + str = QString("%1").arg((int)val); 398 + else 399 + str = QString("%1").arg(val, 0, 'f', digits); 400 + str += " cycles"; 401 + AddLine(name, NONE, str, comment); 402 + } 403 + else if(m_display_mode == DisplayRawHex) 404 + { 405 + QString str = QString("0x%1").arg(raw_val, 0, 16); 406 + AddLine(name, NONE, str, comment); 407 + } 408 + else if(m_display_mode == DisplayTime && m_emi_freq != 0) 409 + { 410 + float cycle_time_ns = 1000000000.0 / m_emi_freq; 411 + val *= cycle_time_ns; 412 + QString str; 413 + if(val >= 1000) 414 + str = QString::fromWCharArray(L"%1 µs").arg(val / 1000.0, 0, 'f', 2); 415 + else 416 + str = QString("%1 ns").arg(val, 0, 'f', 2); 417 + AddLine(name, NONE, str, comment); 418 + } 419 + else 420 + AddLine(name, raw_val, " cycles", comment); 421 + } 422 + 423 + void EmiAnalyser::FillTable() 424 + { 425 + while(m_panel->count() > 0) 426 + m_panel->removeItem(0); 427 + BackendHelper helper(m_io_backend, m_soc); 428 + soc_word_t value; 429 + 430 + m_emi_freq = 0; 431 + if(helper.ReadRegisterField("CLKCTRL", "CLKSEQ", "BYPASS_EMI", value)) 432 + { 433 + bool ret; 434 + if(value) 435 + { 436 + m_emi_freq = 24000000; 437 + ret = helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_XTAL", value); 438 + } 439 + else 440 + { 441 + m_emi_freq = 480000000; 442 + if(helper.ReadRegisterField("CLKCTRL", "FRAC", "EMIFRAC", value)) 443 + m_emi_freq = 18 * (int64_t)m_emi_freq / value; 444 + else 445 + m_emi_freq = 0; 446 + ret = helper.ReadRegisterField("CLKCTRL", "EMI", "DIV_EMI", value); 447 + } 448 + if(ret) 449 + m_emi_freq /= value; 450 + else 451 + m_emi_freq = 0; 452 + } 453 + 454 + m_emi_freq_label->setText(QString().sprintf("%.3f", m_emi_freq / 1000000.0)); 455 + 456 + NewGroup("Control Parameters"); 457 + if(helper.ReadRegisterField("EMI", "CTRL", "PORT_PRIORITY_ORDER", value)) 458 + { 459 + QStringList ports; 460 + ports << "AXI0" << "AHB1" << "AHB2" << "AHB3"; 461 + QString order; 462 + order += ports[value / 6]; 463 + ports.erase(ports.begin() + value / 6); 464 + int ord[6][3] = { {0, 1, 2}, {2, 0, 1}, {1, 2, 0}, {2, 1, 0}, {1, 0, 2}, {0, 2, 1} }; 465 + for(int i = 0; i < 3; i++) 466 + order += ", " + ports[ord[value][i]]; 467 + AddLine("Port Priority Order", value, "", order); 468 + } 469 + 470 + if(helper.ReadRegisterField("EMI", "CTRL", "MEM_WIDTH", value)) 471 + AddLine("Memory Width", value ? 16 : 8, "-bit"); 472 + 473 + if(helper.ReadRegisterField("DRAM", "CTL03", "AP", value)) 474 + AddLine("Auto Pre-Charge", NONE, value ? "Yes" : "No"); 475 + 476 + bool bypass_mode = false; 477 + if(helper.ReadRegisterField("DRAM", "CTL04", "DLL_BYPASS_MODE", value)) 478 + { 479 + bypass_mode = value == 1; 480 + AddLine("DLL Bypass Mode", NONE, value ? "Yes" : "No"); 481 + } 482 + 483 + if(helper.ReadRegisterField("DRAM", "CTL05", "EN_LOWPOWER_MODE", value)) 484 + AddLine("Low Power Mode", NONE, value ? "Enabled" : "Disabled"); 485 + 486 + if(helper.ReadRegisterField("DRAM", "CTL08", "SREFRESH", value)) 487 + AddLine("Self Refresh", NONE, value ? "Yes" : "No"); 488 + 489 + if(helper.ReadRegisterField("DRAM", "CTL08", "SDR_MODE", value)) 490 + AddLine("Mode", NONE, value ? "SDR" : "DDR"); 491 + 492 + if(helper.ReadRegisterField("DRAM", "CTL10", "ADDR_PINS", value)) 493 + AddLine("Address Pins", 13 - value, ""); 494 + 495 + if(helper.ReadRegisterField("DRAM", "CTL11", "ADDR_PINS", value)) 496 + AddLine("Column Size", 12 - value, "-bit"); 497 + 498 + if(helper.ReadRegisterField("DRAM", "CTL11", "ADDR_PINS", value)) 499 + AddLine("Encoded CAS", value, "Memory device dependent"); 500 + 501 + if(helper.ReadRegisterField("DRAM", "CTL14", "CS_MAP", value)) 502 + { 503 + QString v; 504 + for(int i = 0; i < 4; i++) 505 + if(value & (1 << i)) 506 + { 507 + if(v.size() != 0) 508 + v += " "; 509 + v += QString("%1").arg(i); 510 + } 511 + AddLine("Chip Select Pins", NONE, v, ""); 512 + } 513 + 514 + if(helper.ReadRegisterField("DRAM", "CTL37", "TREF_ENABLE", value)) 515 + AddLine("Refresh Commands", NONE, value ? "Enabled" : "Disabled", "Issue self-refresh every TREF cycles"); 516 + 517 + NewGroup("Frequency Parameters"); 518 + 519 + if(helper.ReadRegisterField("DRAM", "CTL13", "CASLAT_LIN_GATE", value)) 520 + { 521 + if(value >= 3 && value <= 10 && value != 9) 522 + { 523 + float v = (value / 2) + 0.5 * (value % 2); 524 + AddCycleLine("CAS Gate", value, v, 1, ""); 525 + } 526 + else 527 + AddLine("CAS Gate", NONE, "Reserved", "Reserved value"); 528 + } 529 + if(helper.ReadRegisterField("DRAM", "CTL13", "CASLAT_LIN", value)) 530 + { 531 + if(value >= 3 && value <= 10 && value != 9) 532 + { 533 + float v = (value / 2) + 0.5 * (value % 2); 534 + AddCycleLine("CAS Latency", value, v, 1, ""); 535 + } 536 + else 537 + AddLine("CAS Latency", NONE, "Reserved", "Reserved value"); 538 + } 539 + 540 + if(helper.ReadRegisterField("DRAM", "CTL12", "TCKE", value)) 541 + AddCycleLine("tCKE", value, value, 0, "Minimum CKE pulse width"); 542 + 543 + if(helper.ReadRegisterField("DRAM", "CTL15", "TDAL", value)) 544 + AddCycleLine("tDAL", value, value, 0, "Auto pre-charge write recovery time"); 545 + 546 + if(helper.ReadRegisterField("DRAM", "CTL31", "TDLL", value)) 547 + AddCycleLine("tDLL", value, value, 0, "DLL lock time"); 548 + 549 + if(helper.ReadRegisterField("DRAM", "CTL10", "TEMRS", value)) 550 + AddCycleLine("tEMRS", value, value, 0, "Extended mode parameter set time"); 551 + 552 + if(helper.ReadRegisterField("DRAM", "CTL34", "TINIT", value)) 553 + AddCycleLine("tINIT", value, value, 0, "Initialisation time"); 554 + 555 + if(helper.ReadRegisterField("DRAM", "CTL16", "TMRD", value)) 556 + AddCycleLine("tMRD", value, value, 0, "Mode register set command time"); 557 + 558 + if(helper.ReadRegisterField("DRAM", "CTL40", "TPDEX", value)) 559 + AddCycleLine("tPDEX", value, value, 0, "Power down exit time"); 560 + 561 + if(helper.ReadRegisterField("DRAM", "CTL32", "TRAS_MAX", value)) 562 + AddCycleLine("tRAS Max", value, value, 0, "Maximum row activate time"); 563 + 564 + if(helper.ReadRegisterField("DRAM", "CTL20", "TRAS_MIN", value)) 565 + AddCycleLine("tRAS Min", value, value, 0, "Minimum row activate time"); 566 + 567 + if(helper.ReadRegisterField("DRAM", "CTL17", "TRC", value)) 568 + AddCycleLine("tRC", value, value, 0, "Activate to activate delay (same bank)"); 569 + 570 + if(helper.ReadRegisterField("DRAM", "CTL20", "TRCD_INT", value)) 571 + AddCycleLine("tRCD", value, value, 0, "RAS to CAS"); 572 + 573 + if(helper.ReadRegisterField("DRAM", "CTL26", "TREF", value)) 574 + AddCycleLine("tREF", value, value, 0, "Refresh to refresh time"); 575 + 576 + if(helper.ReadRegisterField("DRAM", "CTL21", "TRFC", value)) 577 + AddCycleLine("tRFC", value, value, 0, "Refresh command time"); 578 + 579 + if(helper.ReadRegisterField("DRAM", "CTL15", "TRP", value)) 580 + AddCycleLine("tRP", value, value, 0, "Pre-charge command time"); 581 + 582 + if(helper.ReadRegisterField("DRAM", "CTL12", "TRRD", value)) 583 + AddCycleLine("tRRD", value, value, 0, "Activate to activate delay (different banks)"); 584 + 585 + if(helper.ReadRegisterField("DRAM", "CTL12", "TWR_INT", value)) 586 + AddCycleLine("tWR", value, value, 0, "Write recovery time"); 587 + 588 + if(helper.ReadRegisterField("DRAM", "CTL13", "TWTR", value)) 589 + AddCycleLine("tWTR", value, value, 0, "Write to read delay"); 590 + 591 + if(helper.ReadRegisterField("DRAM", "CTL32", "TXSNR", value)) 592 + AddCycleLine("tXSNR", value, value, 0, ""); 593 + 594 + if(helper.ReadRegisterField("DRAM", "CTL33", "TXSR", value)) 595 + AddCycleLine("tXSR", value, value, 0, "Self-refresh exit time"); 596 + 597 + NewGroup("DLL Parameters"); 598 + 599 + if(bypass_mode) 600 + { 601 + if(helper.ReadRegisterField("DRAM", "CTL19", "DLL_DQS_DELAY_0_BYPASS", value)) 602 + AddLine("DLL DQS Delay 0", value, "", "In 1/128 fraction of a cycle (bypass mode)"); 603 + 604 + if(helper.ReadRegisterField("DRAM", "CTL19", "DLL_DQS_DELAY_1_BYPASS", value)) 605 + AddLine("DLL DQS Delay 1", value, "", "In 1/128 fraction of a cycle (bypass mode)"); 606 + 607 + if(helper.ReadRegisterField("DRAM", "CTL19", "DQS_OUT_SHIFT_BYPASS", value)) 608 + AddLine("DQS Out Delay", value, "", "(bypass mode)"); 609 + 610 + if(helper.ReadRegisterField("DRAM", "CTL20", "WR_DQS_SHIFT_BYPASS", value)) 611 + AddLine("DQS Write Delay", value, "", "(bypass mode)"); 612 + } 613 + else 614 + { 615 + if(helper.ReadRegisterField("DRAM", "CTL17", "DLL_START_POINT", value)) 616 + AddLine("DLL Start Point", value, "", "Initial delay count"); 617 + 618 + if(helper.ReadRegisterField("DRAM", "CTL17", "DLL_INCREMENT", value)) 619 + AddLine("DLL Increment", value, "", "Delay increment"); 620 + 621 + if(helper.ReadRegisterField("DRAM", "CTL18", "DLL_DQS_DELAY_0", value)) 622 + AddLine("DLL DQS Delay 0", value, "", "In 1/128 fraction of a cycle"); 623 + 624 + if(helper.ReadRegisterField("DRAM", "CTL18", "DLL_DQS_DELAY_1", value)) 625 + AddLine("DLL DQS Delay 1", value, "", "In 1/128 fraction of a cycle"); 626 + 627 + if(helper.ReadRegisterField("DRAM", "CTL19", "DQS_OUT_SHIFT", value)) 628 + AddLine("DQS Out Delay", value, "", ""); 629 + 630 + if(helper.ReadRegisterField("DRAM", "CTL20", "WR_DQS_SHIFT", value)) 631 + AddLine("DQS Write Delay", value, "", ""); 632 + } 633 + 634 + } 635 + 636 + static TmplAnalyserFactory< EmiAnalyser > g_emi_factory(true, "EMI Analyser");
+95
utils/regtools/qeditor/std_analysers.h
··· 1 + #ifndef _STDANALYSER_H_ 2 + #define _STDANALYSER_H_ 3 + 4 + #include "analyser.h" 5 + 6 + #include <QGroupBox> 7 + #include <QTreeWidget> 8 + #include <QVBoxLayout> 9 + #include <QHBoxLayout> 10 + #include <QTableWidget> 11 + #include <QHeaderView> 12 + #include <QToolBox> 13 + #include <QComboBox> 14 + #include <QLabel> 15 + #include <QLineEdit> 16 + #include "analyser.h" 17 + #include "collapsiblepanel.h" 18 + 19 + /** 20 + * Clock analyser 21 + */ 22 + 23 + class ClockAnalyser : public Analyser 24 + { 25 + Q_OBJECT 26 + public: 27 + ClockAnalyser(const soc_t& soc, IoBackend *backend); 28 + virtual ~ClockAnalyser(); 29 + virtual QWidget *GetWidget(); 30 + static bool SupportSoc(const QString& soc_name); 31 + 32 + private: 33 + QString GetFreq(unsigned freq); 34 + 35 + enum 36 + { 37 + DISABLED = 0, 38 + INVALID = -1, 39 + FROM_PARENT = -2, 40 + }; 41 + 42 + QTreeWidgetItem *AddClock(QTreeWidgetItem *parent, const QString& name, int freq, int mul = 1, int div = 1); 43 + int GetClockFreq(QTreeWidgetItem *item); 44 + void FillTree(); 45 + 46 + private: 47 + QGroupBox *m_group; 48 + QTreeWidget *m_tree_widget; 49 + }; 50 + 51 + /** 52 + * EMI analyser 53 + */ 54 + class EmiAnalyser : public Analyser 55 + { 56 + Q_OBJECT 57 + public: 58 + EmiAnalyser(const soc_t& soc, IoBackend *backend); 59 + virtual ~EmiAnalyser(); 60 + virtual QWidget *GetWidget(); 61 + 62 + static bool SupportSoc(const QString& soc_name); 63 + 64 + private slots: 65 + void OnChangeDisplayMode(int index); 66 + 67 + private: 68 + enum DisplayMode 69 + { 70 + DisplayCycles, 71 + DisplayRawHex, 72 + DisplayTime, 73 + }; 74 + 75 + enum 76 + { 77 + NONE = -999999, 78 + INVALID = -1000000 79 + }; 80 + 81 + void NewGroup(const QString& name); 82 + void AddLine(const QString& name, int value, const QString& unit, const QString& comment = ""); 83 + void AddCycleLine(const QString& name, unsigned raw_val, float val, int digits, const QString& comment = ""); 84 + void FillTable(); 85 + 86 + private: 87 + QGroupBox *m_group; 88 + QComboBox *m_display_selector; 89 + QToolBox *m_panel; 90 + DisplayMode m_display_mode; 91 + unsigned m_emi_freq; 92 + QLineEdit *m_emi_freq_label; 93 + }; 94 + 95 + #endif /* _STDANALYSER_H_ */