diff options
Diffstat (limited to 'src/devices/pic/gui')
-rw-r--r-- | src/devices/pic/gui/Makefile.am | 9 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_config_editor.cpp | 68 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_config_editor.h | 37 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_config_word_editor.cpp | 196 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_config_word_editor.h | 70 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_group_ui.cpp | 87 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_group_ui.h | 29 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_hex_view.cpp | 60 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_hex_view.h | 39 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_memory_editor.cpp | 404 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_memory_editor.h | 189 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_prog_group_ui.cpp | 41 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_prog_group_ui.h | 31 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_register_view.cpp | 329 | ||||
-rw-r--r-- | src/devices/pic/gui/pic_register_view.h | 88 |
15 files changed, 1677 insertions, 0 deletions
diff --git a/src/devices/pic/gui/Makefile.am b/src/devices/pic/gui/Makefile.am new file mode 100644 index 0000000..72f3165 --- /dev/null +++ b/src/devices/pic/gui/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libpicui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libpicui.la + + +libpicui_la_SOURCES = pic_config_editor.cpp \ + pic_config_word_editor.cpp pic_hex_view.cpp pic_memory_editor.cpp pic_register_view.cpp pic_group_ui.cpp \ + pic_prog_group_ui.cpp diff --git a/src/devices/pic/gui/pic_config_editor.cpp b/src/devices/pic/gui/pic_config_editor.cpp new file mode 100644 index 0000000..1812bbf --- /dev/null +++ b/src/devices/pic/gui/pic_config_editor.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_config_editor.h" + +#include <qlayout.h> +#include <qvgroupbox.h> +#include <qapplication.h> + +#include "pic_config_word_editor.h" +#include "common/common/misc.h" +#include "common/gui/misc_gui.h" + +//---------------------------------------------------------------------------- +Pic::MemoryConfigEditorWidget::MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent) + : Device::MemoryEditorGroup(&memory, parent, "pic_config_editor_widget"), + MemoryCaster(MemoryRangeType::Config, memory) +{ + QHBoxLayout *hb = new QHBoxLayout(_top); + + TabWidget *tabw = 0; + uint nbWords = device().nbWords(MemoryRangeType::Config); + if ( nbWords>1 ) { + tabw = new TabWidget(this); + tabw->setIgnoreWheelEvent(true); + hb->addWidget(tabw); + } + + for(uint i=0; i<nbWords; ++i) { + //qDebug("BinWordsEditor for config word #%i", i); + //uint address = device().range(Device::MemoryConfig).start + device().addressIncrement(Device::MemoryConfig) * i; + //qDebug("address: %s %s nb: %i", toHex(address, 8).data(), device().configWord(i).name.latin1(), device().configWord(i).masks.count()); + if ( device().config()._words[i].masks.count()==0 ) continue; + QWidget *page = 0; + if ( nbWords>1 ) { + page = new QWidget(tabw); + tabw->addTab(page, device().config()._words[i].name); + } else { + page = new QGroupBox(this); + hb->addWidget(page); + } + QVBoxLayout *vbox = new QVBoxLayout(page, 10, 10); + QHBoxLayout *hbox = new QHBoxLayout(vbox); + ConfigWordEditor *we = new ConfigWordEditor(memory, i, withWordEditor, page); + addEditor(we); + hbox->addWidget(we); + hbox->addStretch(1); + vbox->addStretch(1); + } +} + +//---------------------------------------------------------------------------- +Pic::MemoryConfigEditor::MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, MemoryRangeType::Config, memory, parent, "pic_config_editor") +{} + +void Pic::MemoryConfigEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + MemoryConfigEditorWidget *w = new MemoryConfigEditorWidget(memory(), true, this); + addEditor(w); + _top->addWidget(w); +} diff --git a/src/devices/pic/gui/pic_config_editor.h b/src/devices/pic/gui/pic_config_editor.h new file mode 100644 index 0000000..888debf --- /dev/null +++ b/src/devices/pic/gui/pic_config_editor.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_CONFIG_EDITOR_H +#define PIC_CONFIG_EDITOR_H + +#include "pic_memory_editor.h" + +//---------------------------------------------------------------------------- +namespace Pic +{ +class HexView; + +class MemoryConfigEditorWidget : public Device::MemoryEditorGroup, public MemoryCaster +{ +Q_OBJECT +public: + MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class MemoryConfigEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_config_word_editor.cpp b/src/devices/pic/gui/pic_config_word_editor.cpp new file mode 100644 index 0000000..23e4bce --- /dev/null +++ b/src/devices/pic/gui/pic_config_word_editor.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_config_word_editor.h" + +#include <qlabel.h> +#include <qlayout.h> +#include <qcombobox.h> +#include <klocale.h> + +#include "common/common/misc.h" +#include "common/gui/misc_gui.h" + +//---------------------------------------------------------------------------- +Pic::ConfigWordComboBox::ConfigWordComboBox(QWidget *parent) + : ComboBox(parent) +{ + setIgnoreWheelEvent(true); +} + +uint Pic::ConfigWordComboBox::index() const +{ + if ( isValid() ) return _map[currentItem()]; + if ( currentItem()==0 ) return _invalidIndex; + return _map[currentItem()-1]; +} + +void Pic::ConfigWordComboBox::setItem(uint i) +{ + if ( !isValid() ) removeItem(0); + for (uint l=0; l<_map.count(); l++) + if ( _map[l]==i ) setCurrentItem(l); +} + +void Pic::ConfigWordComboBox::setInvalidItem(uint i, const QString &label) +{ + if ( !isValid() ) changeItem(label, 0); + else insertItem(label, 0); + setCurrentItem(0); + _invalidIndex = i; +} + +//---------------------------------------------------------------------------- +Pic::ConfigWordDialog::ConfigWordDialog(const Memory &memory, uint ci, QWidget *parent) + : Dialog(parent, "config_word_dialog", true, i18n("Config Word Details"), Close, Close, false) +{ + uint nbChars = memory.device().nbCharsWord(MemoryRangeType::Config); + const Config::Word &cword = memory.device().config()._words[ci]; + + QGridLayout *grid = new QGridLayout(mainWidget(), 0, 0, 10, 10); + uint row = 0; + QLabel *label = new QLabel(i18n("Name:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(cword.name, mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Index:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(QString::number(ci), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Raw Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(memory.word(MemoryRangeType::Config, ci), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(memory.normalizedWord(MemoryRangeType::Config, ci), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Raw Blank Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.bvalue, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Used Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.usedMask(), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Write Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.wmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Protected Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.pmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Checksum Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.cmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; +} + +//---------------------------------------------------------------------------- +Pic::ConfigWordEditor::ConfigWordEditor(Memory &memory, uint ci, bool withWordEditor, QWidget *parent) + : MemoryEditor(MemoryRangeType::Config, memory, parent, "pic_config_word_editor"), _configIndex(ci) +{ + if (withWordEditor) { + QHBoxLayout *hbox = new QHBoxLayout(_top); + _mdb = new MemoryRangeEditor(MemoryRangeType::Config, memory, 1, 1, ci, 1, this); + _mdb->init(); + connect(_mdb, SIGNAL(modified()), SIGNAL(modified())); + connect(_mdb, SIGNAL(modified()), SLOT(updateDisplay())); + hbox->addWidget(_mdb); + KPushButton *button = new KPushButton(i18n("Details..."), this); + button->setFixedHeight(button->sizeHint().height()); + connect(button, SIGNAL(clicked()), SLOT(showDialog())); + hbox->addWidget(button); + hbox->addStretch(1); + } else _mdb = 0; + + QGridLayout *grid = new QGridLayout(_top); + grid->setColStretch(2, 1); + const Config::Word &cword = device().config()._words[ci]; + _combos.resize(cword.masks.count()); + uint nbChars = device().nbCharsWord(MemoryRangeType::Config); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = cword.masks[k]; + QLabel *label = new QLabel(Config::maskLabel(cmask.name) + ":", this); + grid->addWidget(label, k, 0); + label = new QLabel(cmask.name, this); + grid->addWidget(label, k, 1); + _combos[k] = new ConfigWordComboBox(this); + for (uint i=0; i<cmask.values.count(); i++) { + if ( !cmask.values[i].isValid() ) continue; + QString label = Config::valueLabel(cmask.name, cmask.values[i].name); + label += " (" + toHexLabel(cmask.values[i].value, nbChars) + ")"; + _combos[k]->appendItem(label, i); + } + connect(_combos[k], SIGNAL(activated(int)), SLOT(slotModified())); + grid->addWidget(_combos[k], k, 2); + } +} + +void Pic::ConfigWordEditor::setReadOnly(bool readOnly) +{ + if (_mdb) _mdb->setReadOnly(readOnly); + const Config::Word &cword = device().config()._words[_configIndex]; + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = cword.masks[k]; + _combos[k]->setEnabled(!readOnly && !cmask.value.isOverlapping(cword.pmask) && cmask.values.count()!=1); + } +} + +void Pic::ConfigWordEditor::slotModified() +{ + BitValue v = memory().word(MemoryRangeType::Config, _configIndex); + //qDebug("BinWordEditor::slotModified %i: %s", _configIndex, toHex(v, 4).data()); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = device().config()._words[_configIndex].masks[k]; + v = v.clearMaskBits(cmask.value); + v |= cmask.values[_combos[k]->index()].value; // set value + } + memory().setWord(MemoryRangeType::Config, _configIndex, v); + //qDebug(" now: %s", toHex(v, 4).data()); + if (_mdb) _mdb->updateDisplay(); + emit modified(); +} + +void Pic::ConfigWordEditor::updateDisplay() +{ + BitValue v = memory().word(MemoryRangeType::Config, _configIndex); + uint nbChars = device().nbCharsWord(MemoryRangeType::Config); + //qDebug("BinWordEditor::updateDisplay %i: %s", _configIndex, toHex(v, 4).data()); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = device().config()._words[_configIndex].masks[k]; + for (int i=cmask.values.count()-1; i>=0; i--) { + if ( cmask.values[i].value.isInside(v) ) { + if ( cmask.values[i].isValid() ) _combos[k]->setItem(i); + else { + QString label = i18n("<invalid>") + " (" + toHexLabel(cmask.values[i].value, nbChars) + ")"; + _combos[k]->setInvalidItem(i, label); + } + break; + } + } + } + if (_mdb) _mdb->updateDisplay(); +} + +void Pic::ConfigWordEditor::showDialog() +{ + ConfigWordDialog dialog(memory(), _configIndex, this); + dialog.exec(); +} diff --git a/src/devices/pic/gui/pic_config_word_editor.h b/src/devices/pic/gui/pic_config_word_editor.h new file mode 100644 index 0000000..8f483c7 --- /dev/null +++ b/src/devices/pic/gui/pic_config_word_editor.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_CONFIG_WORD_EDITOR_H +#define PIC_CONFIG_WORD_EDITOR_H + +#include <qcombobox.h> + +#include "common/gui/dialog.h" +#include "common/gui/misc_gui.h" +#include "pic_memory_editor.h" + +namespace Pic +{ +//---------------------------------------------------------------------------- +class ConfigWordDialog : public Dialog +{ +Q_OBJECT +public: + ConfigWordDialog(const Memory &memory, uint index, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class ConfigWordComboBox : public ComboBox +{ +Q_OBJECT +public: + ConfigWordComboBox(QWidget *parent); + void appendItem(const QString &text, uint index) { insertItem(text); _map.append(index); } + uint index() const; + void setItem(uint index); + void setInvalidItem(uint index, const QString &label); + +private: + QValueVector<uint> _map; // item index -> value index + uint _invalidIndex; // if invalid -> value index + + bool isValid() const { return uint(count())==_map.count(); } +}; + +//---------------------------------------------------------------------------- +class ConfigWordEditor : public MemoryEditor +{ +Q_OBJECT +public: + ConfigWordEditor(Memory &memory, uint index, bool withWordEditor, QWidget *parent); + virtual void setReadOnly(bool readOnly); + +public slots: + virtual void updateDisplay(); + +private slots: + void slotModified(); + void showDialog(); + +private: + uint _configIndex; + MemoryRangeEditor *_mdb; + QValueVector<ConfigWordComboBox *> _combos; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_group_ui.cpp b/src/devices/pic/gui/pic_group_ui.cpp new file mode 100644 index 0000000..3f7a84c --- /dev/null +++ b/src/devices/pic/gui/pic_group_ui.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_group_ui.h" + +#include <kaction.h> + +#include "libgui/main_global.h" +#include "pic_hex_view.h" +#include "pic_register_view.h" +#include "pic_config_editor.h" +#include "coff/base/text_coff.h" +#include "libgui/gui_debug_manager.h" +#include "common/gui/list_container.h" + +Device::HexView *Pic::GroupUI::createHexView(const HexEditor &editor, QWidget *parent) const +{ + return new HexView(editor, parent); +} + +Register::View *Pic::GroupUI::createRegisterView(QWidget *parent) const +{ + return new RegisterView(parent); +} + +Device::MemoryEditor *Pic::GroupUI::createConfigEditor(Device::Memory &memory, QWidget *parent) const +{ + return new MemoryConfigEditorWidget(static_cast<Memory &>(memory), false, parent); +} + +void Pic::GroupUI::fillWatchListContainer(ListContainer *container, QValueVector<Register::TypeData> &ids) const +{ + ids.clear(); + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + ListContainer *branch = container->appendBranch(i18n("SFRs")); + QValueVector<Pic::RegisterNameData> list = Pic::sfrList(data); + for (uint i=0; i<list.count(); i++) { + branch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + } + branch = container->appendBranch(i18n("I/Os")); + for (uint i=0; i<Device::MAX_NB_PORTS; i++) { + if ( !rdata.hasPort(i) ) continue; + QString name = rdata.portName(i); + branch->appendItem(name, ids.count(), ListContainer::UnChecked); + ids.append(Register::TypeData(rdata.sfrs[name].address, rdata.nbChars())); + } + branch = container->appendBranch(i18n("GPRs")); + const Coff::Object *coff = Debugger::manager->coff(); + list = Pic::gprList(data, coff); + for (uint k=0; k<rdata.nbBanks; k++) { + if ( !rdata.isBankUsed(k) ) continue; + ListContainer *bbranch = (rdata.nbBanks==1 ? branch : branch->appendBranch(i18n("Bank %1").arg(k))); + uint nb = 0; + for (uint i=0; i<list.count(); i++) { + if ( rdata.bankFromAddress(list[i].data().address())!=k ) continue; + bbranch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + nb++; + } + } + branch = container->appendBranch(i18n("Variables")); + if (coff) { + list = Pic::variableList(data, *coff); + if ( list.count()==0 ) { + branch->appendItem(i18n("No variable"), ids.count(), ListContainer::Disabled); + ids.append(Register::TypeData()); + } else for (uint i=0; i<list.count(); i++) { + branch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + } + } else { + branch->appendItem(i18n("Please compile the current project"), ids.count(), ListContainer::Disabled); + ids.append(Register::TypeData()); + } +} + +Register::ListViewItem *Pic::GroupUI::createWatchItem(const Register::TypeData &data, KListViewItem *parent) const +{ + return new Pic::RegisterListViewItem(data, parent); +} diff --git a/src/devices/pic/gui/pic_group_ui.h b/src/devices/pic/gui/pic_group_ui.h new file mode 100644 index 0000000..a8bee66 --- /dev/null +++ b/src/devices/pic/gui/pic_group_ui.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_GROUP_UI_H +#define PIC_GROUP_UI_H + +#include "devices/gui/device_group_ui.h" + +namespace Pic +{ + +class GroupUI : public Device::GroupUI +{ +public: + virtual Device::HexView *createHexView(const HexEditor &editor, QWidget *parent) const; + virtual Register::View *createRegisterView(QWidget *parent) const; + virtual Device::MemoryEditor *createConfigEditor(Device::Memory &memory, QWidget *parent) const; + virtual void fillWatchListContainer(ListContainer *container, QValueVector<Register::TypeData> &ids) const; + virtual Register::ListViewItem *createWatchItem(const Register::TypeData &data, KListViewItem *parent) const; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_hex_view.cpp b/src/devices/pic/gui/pic_hex_view.cpp new file mode 100644 index 0000000..07a1938 --- /dev/null +++ b/src/devices/pic/gui/pic_hex_view.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_hex_view.h" + +#include <qlayout.h> +#include <qlabel.h> + +#include <klocale.h> + +#include "pic_memory_editor.h" +#include "pic_config_editor.h" + +Pic::HexView::HexView(const HexEditor &editor, QWidget *parent) + : Device::HexView(editor, parent, "pic_hex_view") +{} + +const Pic::MemoryRangeType::Type Pic::HexView::MEMORY_DATA[] = { + MemoryRangeType::Code, MemoryRangeType::Config, MemoryRangeType::Eeprom, MemoryRangeType::UserId, + MemoryRangeType::Cal, MemoryRangeType::Nb_Types +}; + +void Pic::HexView::display() +{ + bool first = true; + for (uint i=0; MEMORY_DATA[i]!=MemoryRangeType::Nb_Types; i++) { + Pic::MemoryRangeType type = MEMORY_DATA[i]; + if ( !memory()->device().isReadable(type) ) continue; + Device::MemoryTypeEditor *e = 0; + switch (type.type()) { + case MemoryRangeType::Config: e = new MemoryConfigEditor(this, *memory(), this); break; + case MemoryRangeType::Cal: e = new MemoryCalibrationEditor(this, *memory(), this); break; + case MemoryRangeType::Code: + case MemoryRangeType::Eeprom: e = new MemoryTypeRangeEditor(this, type, *memory(), this); break; + case MemoryRangeType::UserId: e = new MemoryUserIdEditor(this, *memory(), this); break; + case MemoryRangeType::DeviceId: + case MemoryRangeType::HardwareStack: + case MemoryRangeType::ProgramExecutive: + case MemoryRangeType::DebugVector: + case MemoryRangeType::CalBackup: + case MemoryRangeType::Nb_Types: Q_ASSERT(false); break; + } + e->init(first); + e->show(); + _top->addWidget(e); + addEditor(e); + first = false; + } +} + +BitValue Pic::HexView::checksum() const +{ + return (_memory ? memory()->checksum() : 0x0000); +} diff --git a/src/devices/pic/gui/pic_hex_view.h b/src/devices/pic/gui/pic_hex_view.h new file mode 100644 index 0000000..2086ccb --- /dev/null +++ b/src/devices/pic/gui/pic_hex_view.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_HEX_VIEW_H +#define PIC_HEX_VIEW_H + +class QVBoxLayout; + +#include "devices/gui/hex_view.h" +#include "devices/pic/pic/pic_memory.h" + +namespace Pic +{ + +class HexView : public Device::HexView +{ +Q_OBJECT +public: + HexView(const HexEditor &editor, QWidget *parent); + Memory *memory() { return static_cast<Memory *>(_memory); } + const Memory *memory() const { return static_cast<Memory *>(_memory); } + virtual uint nbChecksumChars() const { return 4; } + virtual BitValue checksum() const; + +private: + static const MemoryRangeType::Type MEMORY_DATA[]; + + virtual void display(); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_memory_editor.cpp b/src/devices/pic/gui/pic_memory_editor.cpp new file mode 100644 index 0000000..3d78097 --- /dev/null +++ b/src/devices/pic/gui/pic_memory_editor.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_memory_editor.h" + +#include <qframe.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qscrollbar.h> +#include <qgrid.h> +#include <qhbox.h> +#include <qtooltip.h> +#include <qregexp.h> +#include <qcolor.h> +#include <qlayout.h> +#include <qpixmap.h> + +#include <klocale.h> +#include <kpushbutton.h> +#include <kaction.h> + +#include "common/common/misc.h" +#include "pic_config_editor.h" +#include "libgui/toplevel.h" +#include "libgui/main_global.h" +#include "devices/pic/prog/pic_prog.h" +#include "libgui/global_config.h" +#include "pic_hex_view.h" + +//----------------------------------------------------------------------------- +Pic::MemoryEditorLegend::Data::Data(const QString &text, QWidget *parent) +{ + button = new PopupButton(text, parent); + KActionCollection *ac = 0; + KAction *a = new KAction(i18n("Go to start"), "top", 0, parent, SLOT(gotoStart()), ac); + actions.append(a); + button->appendAction(a); + a = new KAction(i18n("Go to end"), "bottom", 0, parent, SLOT(gotoEnd()), ac); + actions.append(a); + button->appendAction(a); + label = new QLabel(parent); +} + +void Pic::MemoryEditorLegend::Data::setProtected(bool on) +{ + if (on) label->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor()); + else label->unsetPalette(); +} + +bool Pic::MemoryEditorLegend::Data::hasAction(const KAction *action) const +{ + for (uint i=0; i<actions.count(); i++) if ( actions[i]==action ) return true; + return false; +} + +//----------------------------------------------------------------------------- +const char * const Pic::MemoryEditorLegend::BLOCK_COLORS[Protection::MAX_NB_BLOCKS] = { + "#88FF88", "#88FFFF", "#FFFF88", "#FF88FF", "#0088FF", "#88FF00", "#00FF88", "#FF8800" +}; + +Pic::MemoryEditorLegend::MemoryEditorLegend(MemoryRangeType type, Memory &memory, QWidget *parent) + : MemoryEditor(type, memory, parent, "memory_displayer_legend") +{ + QGridLayout *grid = new QGridLayout(_top); + + QWidget *w = new QWidget(this); + w->setFixedWidth(20); + w->setPaletteBackgroundColor(protectedColor()); + grid->addWidget(w, 0, 0); + const Protection &protection = device().config().protection(); + QString s = (protection.family()==Protection::CodeGuard ? i18n("High Security") : i18n("Code protection")); + QLabel *label = new QLabel(s, this); + grid->addMultiCellWidget(label, 0,0, 1,2); + grid->addRowSpacing(1, 10); + uint row = 2; + + if ( type==MemoryRangeType::Code && protection.hasBootBlock() ) { + w = new QWidget(this); + w->setFixedWidth(20); + w->setPaletteBackgroundColor(bootColor()); + grid->addWidget(w, row, 0); + _boot = Data(protection.bootLabel(), this); + grid->addWidget(_boot.button, row, 1); + grid->addWidget(_boot.label, row, 2); + row++; + } + + uint nb = (type==MemoryRangeType::Code ? protection.nbBlocks() : 0); + for (uint i=0; i<nb; i++) { + w = new QWidget(this); + w->setFixedWidth(20); + w->setPaletteBackgroundColor(blockColor(i)); + grid->addWidget(w, row, 0); + _blocks.append(Data(protection.blockLabel(i), this)); + grid->addWidget(_blocks[i].button, row, 1); + grid->addWidget(_blocks[i].label, row, 2); + row++; + } +} + +void Pic::MemoryEditorLegend::updateDisplay() +{ + const Protection &protection = device().config().protection(); + Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected); + uint nbChars = 2 * device().nbBytesAddress(); + if (_boot.label) { + AddressRange r = memory().bootRange(); + if ( r.isEmpty() ) _boot.label->setText(i18n("not present")); + else _boot.label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars))); + _boot.button->setEnabled(!r.isEmpty()); + _boot.setProtected(memory().isBootProtected(ptype)); + } + for (uint i=0; i<_blocks.count(); i++) { + AddressRange r = memory().blockRange(i); + if ( r.isEmpty() ) _blocks[i].label->setText(i18n("not present")); + else _blocks[i].label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars))); + _blocks[i].button->setEnabled(!r.isEmpty()); + _blocks[i].setProtected(memory().isBlockProtected(ptype, i)); + } +} + +void Pic::MemoryEditorLegend::gotoStart() +{ + Address start = device().range(type()).start; + const KAction *action = static_cast<const KAction *>(sender()); + if ( _boot.hasAction(action) ) { + AddressRange r = memory().bootRange(); + emit setStartWord(r.start - start); + return; + } + for (uint i=0; i<_blocks.count(); i++) { + if ( _blocks[i].hasAction(action) ) { + AddressRange r = memory().blockRange(i); + emit setStartWord(r.start - start); + return; + } + } + Q_ASSERT(false); +} + +void Pic::MemoryEditorLegend::gotoEnd() +{ + Address start = device().range(type()).start; + const KAction *action = static_cast<const KAction *>(sender()); + if ( _boot.hasAction(action) ) { + AddressRange r = memory().bootRange(); + emit setEndWord(r.end - start); + return; + } + for (uint i=0; i<_blocks.count(); i++) { + if ( _blocks[i].hasAction(action) ) { + AddressRange r = memory().blockRange(i); + emit setEndWord(r.end - start); + return; + } + } + Q_ASSERT(false); +} + + +//----------------------------------------------------------------------------- +Pic::HexWordEditor::HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent) + : Device::HexWordEditor(memory, memory.device().nbCharsWord(type), parent), + MemoryCaster(type, memory) +{} + +void Pic::HexWordEditor::setWord(BitValue value) +{ + if ( type()==MemoryRangeType::Config ) { + const Config::Word &cword = device().config()._words[_offset]; + value |= cword.usedMask().complementInMask(device().mask(MemoryRangeType::Config)); + } + memory().setWord(type(), _offset, value); +} + +//----------------------------------------------------------------------------- +Pic::MemoryRangeEditor::MemoryRangeEditor(MemoryRangeType type, Memory &memory, + uint nbLines, uint nbCols, + uint wordOffset, int nbWords, QWidget *parent) + : Device::MemoryRangeEditor(memory, nbLines, nbCols, wordOffset, nbWords, parent, "pic_memory_range_editor"), + MemoryCaster(type, memory), _legend(0) +{ + if ( type==MemoryRangeType::Code ) _blockRanges.resize(memory.device().config().protection().nbBlocks()); +} + +void Pic::MemoryRangeEditor::addLegend(QVBoxLayout *vbox) +{ + if ( type()==MemoryRangeType::Code || type()==MemoryRangeType::Eeprom ) { + _legend = new MemoryEditorLegend(type(), memory(), this); + connect(_legend, SIGNAL(setStartWord(int)), SLOT(setStartWord(int))); + connect(_legend, SIGNAL(setEndWord(int)), SLOT(setEndWord(int))); + vbox->addWidget(_legend); + } +} + +bool Pic::MemoryRangeEditor::isRangeReadOnly() const +{ + return ( (type().data().properties & ReadOnly) || type()==MemoryRangeType::CalBackup ); +} + +void Pic::MemoryRangeEditor::updateDisplay() +{ + const Protection &protection = device().config().protection(); + if ( type()==MemoryRangeType::Code ) { + if ( protection.hasBootBlock() ) _bootRange = memory().bootRange(); + for (uint k=0; k<_blockRanges.count(); k++) + _blockRanges[k] = memory().blockRange(k); + } + Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected); + _codeProtected = memory().protectedRanges(ptype, type()); + Device::MemoryRangeEditor::updateDisplay(); + if (_legend) _legend->updateDisplay(); +} + +void Pic::MemoryRangeEditor::updateAddressColor(uint i, Address address) +{ + if ( _codeProtected.contains(address) ) + _addresses[i]->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor()); + else _addresses[i]->unsetPalette(); + _blocks[i]->unsetPalette(); + if ( type()==MemoryRangeType::Code ) { + if ( _bootRange.contains(address) ) _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::bootColor()); + else for (uint k=0; k<_blockRanges.count(); k++) { + if ( !_blockRanges[k].contains(address) ) continue; + _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::blockColor(k)); + break; + } + } +} + +Device::HexWordEditor *Pic::MemoryRangeEditor::createHexWordEditor(QWidget *parent) +{ + return new HexWordEditor(type(), memory(), parent); +} + +//----------------------------------------------------------------------------- +Pic::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name) + : Device::MemoryTypeEditor(hexview, memory, parent, name), MemoryCaster(type, memory) +{} + +void Pic::MemoryTypeEditor::init(bool first) +{ + Device::MemoryTypeEditor::init(first); + _title->setText(type().label()); + + uint nbChars = device().nbCharsWord(type()); + QString add; + if ( type()==MemoryRangeType::UserId ) add = i18n(" - recommended mask: %1").arg(toHexLabel(device().userIdRecommendedMask(), nbChars)); + if ( type()==MemoryRangeType::Cal && _hexview ) add = i18n(" - not programmed by default"); + QString comment = i18n("%1-bit words - mask: %2") + .arg(device().nbBitsWord(type())).arg(toHexLabel(device().mask(type()), nbChars)); + _comment->setText(comment + add); +} + +bool Pic::MemoryTypeEditor::internalDoAction(Device::Action action) +{ + Programmer::PicBase *prog = static_cast<Programmer::PicBase *>(Main::programmer()); + switch (action) { + case Device::Clear: memory().clear(type()); return true; + case Device::Zero: memory().fill(type(), 0); return true; + case Device::ChecksumCheck : memory().checksumCheckFill(); return true; + case Device::Reload: { + const Memory *omemory = static_cast<const Memory *>(originalMemory()); + Q_ASSERT(omemory); + memory().copyFrom(type(), *omemory); return true; + } + case Device::Program: + prog->programSingle(type(), memory()); + return false; + case Device::Verify: + prog->verifySingle(type(), memory()); + return false; + case Device::Read: + return prog->readSingle(type(), memory()); + case Device::Erase: + prog->eraseSingle(type()); + return false; + case Device::BlankCheck: + prog->blankCheckSingle(type()); + return false; + case Device::Nb_Actions: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +Pic::MemoryTypeRangeEditor::MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, type, memory, parent, "pic_memory_type_range_editor"), _mre(0) +{} + +void Pic::MemoryTypeRangeEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + uint nbLines = 0; + if ( type()==MemoryRangeType::Code ) nbLines = 16; + else if ( type()==MemoryRangeType::Eeprom ) nbLines = 8; + else nbLines = (device().nbWords(type())/8>1 ? 2 : 1); + _mre = new MemoryRangeEditor(type(), memory(), nbLines, 8, 0, -1, this); + addEditor(_mre); + _top->addWidget(_mre); + _mre->init(); +} + +//----------------------------------------------------------------------------- +Pic::MemoryUserIdEditor::MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeRangeEditor(hexview, MemoryRangeType::UserId, memory, parent), _saveReadOnly(false) +{} + +void Pic::MemoryUserIdEditor::init(bool first) +{ + MemoryTypeRangeEditor::init(first); + _setToChecksum = new KToggleAction(i18n("Set to unprotected checksum"), 0, 0, + this, SLOT(toggleSetToChecksum()), Main::toplevel().actionCollection()); + addAction(_setToChecksum); + if ( readConfigEntry(BaseGlobalConfig::UserIdSetToChecksum).toBool() && memory().isClear(MemoryRangeType::UserId) ) { + _setToChecksum->activate(); + toggleSetToChecksum(); + } +} + +void Pic::MemoryUserIdEditor::toggleSetToChecksum() +{ + if ( _setToChecksum->isChecked() ) { + _mre->setComment(i18n("Set to unprotected checksum")); + emit modified(); + } else _mre->setComment(QString::null); + setReadOnly(_saveReadOnly); +} + +void Pic::MemoryUserIdEditor::updateDisplay() +{ + if ( _setToChecksum->isChecked() ) memory().setUserIdToUnprotectedChecksum(); + MemoryTypeRangeEditor::updateDisplay(); +} + +void Pic::MemoryUserIdEditor::setReadOnly(bool readOnly) +{ + _saveReadOnly = readOnly; + MemoryTypeRangeEditor::setReadOnly(readOnly || _setToChecksum->isChecked()); +} + +//----------------------------------------------------------------------------- +Pic::MemoryCalibrationEditor::MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, MemoryRangeType::Cal, memory, parent, "pic_memory_calibration_editor") +{} + +void Pic::MemoryCalibrationEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + MemoryRangeEditor *mre = new MemoryRangeEditor(MemoryRangeType::Cal, memory(), 1, 8, 0, -1, this); + addEditor(mre); + _top->addWidget(mre); + mre->init(); + if ( device().isReadable(MemoryRangeType::CalBackup) ) { + mre = new MemoryRangeEditor(MemoryRangeType::CalBackup, memory(), 1, 8, 0, -1, this); + addEditor(mre); + _top->addWidget(mre); + mre->init(); + mre->setComment(i18n("(backup)")); + } +} + +bool Pic::MemoryCalibrationEditor::hasAction(Device::Action action) const +{ + return ( action==Device::Read || action==Device::Verify || action==Device::Program ); +} + +bool Pic::MemoryCalibrationEditor::internalDoAction(Device::Action action) +{ + Programmer::PicBase *prog = static_cast<Programmer::PicBase *>(Main::programmer()); + switch (action) { + case Device::Reload: { + const Memory *omemory = static_cast<const Memory *>(originalMemory()); + Q_ASSERT(omemory); + memory().copyFrom(MemoryRangeType::Cal, *omemory); + memory().copyFrom(MemoryRangeType::CalBackup, *omemory); + return true; + } + case Device::Program: + if ( prog->programCalibration(memory().arrayForWriting(Pic::MemoryRangeType::Cal)) ) + return prog->readSingle(MemoryRangeType::Cal, memory()); + return false; + case Device::Verify: + prog->verifySingle(MemoryRangeType::Cal, memory()); + return false; + case Device::Read: + return prog->readSingle(MemoryRangeType::Cal, memory()); + case Device::Clear: + case Device::Zero: + case Device::ChecksumCheck: + case Device::Erase: + case Device::BlankCheck: + case Device::Nb_Actions: break; + } + Q_ASSERT(false); + return false; +} diff --git a/src/devices/pic/gui/pic_memory_editor.h b/src/devices/pic/gui/pic_memory_editor.h new file mode 100644 index 0000000..bf67cd1 --- /dev/null +++ b/src/devices/pic/gui/pic_memory_editor.h @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_MEMORY_EDITOR_H +#define PIC_MEMORY_EDITOR_H + +#include <qscrollbar.h> +#include <qgroupbox.h> +class KToggleAction; + +#include "devices/gui/memory_editor.h" +#include "devices/gui/hex_word_editor.h" +#include "devices/pic/pic/pic_memory.h" +class PopupButton; + +namespace Pic +{ +class HexView; + +//----------------------------------------------------------------------------- +class MemoryCaster +{ +public: + MemoryCaster(MemoryRangeType type, Device::Memory &memory) : _type(type), _memory(memory) {} + MemoryRangeType type() const { return _type; } + const Data &device() const { return static_cast<const Data &>(_memory.device()); } + const Memory &memory() const { return static_cast<Memory &>(_memory); } + Memory &memory() { return static_cast<Memory &>(_memory); } + +private: + MemoryRangeType _type; + Device::Memory &_memory; +}; + +//----------------------------------------------------------------------------- +class MemoryEditor : public Device::MemoryEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryEditor(MemoryRangeType type, Memory &memory, QWidget *parent, const char *name) + : Device::MemoryEditor(&memory, parent, name), MemoryCaster(type, memory) {} +}; + +//----------------------------------------------------------------------------- +class MemoryEditorLegend : public MemoryEditor +{ +Q_OBJECT +public: + MemoryEditorLegend(MemoryRangeType type, Memory &memory, QWidget *parent); + virtual void setReadOnly(bool) {} + + static QColor protectedColor() { return QColor("#FF8888"); } + static QColor bootColor() { return QColor("#8888FF"); } + static QColor blockColor(uint i) { return QColor(BLOCK_COLORS[i]); } + +signals: + void setStartWord(int i); + void setEndWord(int i); + +public slots: + virtual void updateDisplay(); + +private slots: + void gotoStart(); + void gotoEnd(); + +private: + class Data { + public: + Data() : button(0), label(0) {} + Data(const QString &text, QWidget *parent); + void setProtected(bool on); + bool hasAction(const KAction *action) const; + PopupButton *button; + QLabel *label; + QValueVector<KAction *> actions; + }; + Data _boot; + QValueVector<Data> _blocks; + + static const char * const BLOCK_COLORS[Protection::MAX_NB_BLOCKS]; +}; + +//----------------------------------------------------------------------------- +class HexWordEditor : public Device::HexWordEditor, public MemoryCaster +{ +Q_OBJECT +public: + HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent); + +private: + virtual BitValue mask() const { return memory().device().mask(type()); } + virtual BitValue normalizeWord(BitValue value) const { return memory().normalizeWord(type(), _offset, value); } + virtual BitValue word() const { return memory().word(type(), _offset); } + virtual void setWord(BitValue value); +}; + +//----------------------------------------------------------------------------- +class MemoryRangeEditor : public Device::MemoryRangeEditor, public MemoryCaster +{ + Q_OBJECT +public: + MemoryRangeEditor(MemoryRangeType type, Memory &memory, + uint nbLines, uint nbCols, uint wordOffset, int nbWords, QWidget *parent); + +public slots: + virtual void updateDisplay(); + +private: + MemoryEditorLegend *_legend; + AddressRange _bootRange; + AddressRangeVector _blockRanges; + AddressRangeVector _codeProtected; + + virtual uint nbWords() const { return device().nbWords(type()); } + virtual uint addressIncrement() const { return device().addressIncrement(type()); } + virtual Address startAddress() const { return device().range(type()).start; } + virtual Device::HexWordEditor *createHexWordEditor(QWidget *parent); + virtual void updateAddressColor(uint i, Address address); + virtual bool isRangeReadOnly() const; + virtual void addLegend(QVBoxLayout *vbox); +}; + +//----------------------------------------------------------------------------- +class MemoryTypeEditor : public Device::MemoryTypeEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name); + virtual void init(bool first); + +private: + virtual bool internalDoAction(Device::Action action); +}; + +//----------------------------------------------------------------------------- +class MemoryTypeRangeEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent); + virtual void init(bool first); + +protected: + MemoryRangeEditor *_mre; +}; + +//----------------------------------------------------------------------------- +class MemoryUserIdEditor : public MemoryTypeRangeEditor +{ +Q_OBJECT +public: + MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); + virtual void setReadOnly(bool readOnly); + +public slots: + virtual void updateDisplay(); + +private slots: + void toggleSetToChecksum(); + +private: + bool _saveReadOnly; + KToggleAction *_setToChecksum; +}; + +//----------------------------------------------------------------------------- +class MemoryCalibrationEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); + +private: + virtual bool hasAction(Device::Action action) const; + virtual bool internalDoAction(Device::Action action); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_prog_group_ui.cpp b/src/devices/pic/gui/pic_prog_group_ui.cpp new file mode 100644 index 0000000..e063b77 --- /dev/null +++ b/src/devices/pic/gui/pic_prog_group_ui.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_prog_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" + +Programmer::PicAdvancedDialog::PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name) + : AdvancedDialog(base, parent, name) +{ + if (_voltagesContainer) { + uint k = _voltagesContainer->numRows(); + for (uint i=0; i<Pic::Nb_VoltageTypes; i++) { + if ( !base.group().canReadVoltage(Pic::VoltageType(i)) ) _voltages[i] = 0; + else { + QLabel *label = new QLabel(i18n(Pic::VOLTAGE_TYPE_LABELS[i]) + ":", _voltagesContainer); + _voltagesContainer->addWidget(label, k,k, 0,0); + _voltages[i] = new QLabel(_voltagesContainer); + _voltagesContainer->addWidget(_voltages[i], k,k, 1,1); + k++; + } + } + } +} + +void Programmer::PicAdvancedDialog::updateDisplay() +{ + ::Programmer::AdvancedDialog::updateDisplay(); + for (uint i=0; i<Pic::Nb_VoltageTypes; i++) { + if ( !base().group().canReadVoltage(Pic::VoltageType(i)) ) continue; + double v = base().voltage(Pic::VoltageType(i)); + if ( v==::Programmer::UNKNOWN_VOLTAGE ) _voltages[i]->setText("---"); + else _voltages[i]->setText(QString("%1 V").arg(v)); + } +} diff --git a/src/devices/pic/gui/pic_prog_group_ui.h b/src/devices/pic/gui/pic_prog_group_ui.h new file mode 100644 index 0000000..75821b5 --- /dev/null +++ b/src/devices/pic/gui/pic_prog_group_ui.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_PROG_GROUP_UI_H +#define PIC_PROG_GROUP_UI_H + +#include "progs/gui/prog_group_ui.h" +#include "devices/pic/prog/pic_prog.h" + +namespace Programmer +{ +class PicAdvancedDialog : public ::Programmer::AdvancedDialog +{ +Q_OBJECT +public: + PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name); + virtual void updateDisplay(); + +private: + QLabel *_voltages[Pic::Nb_VoltageTypes]; + PicBase &base() { return static_cast<PicBase &>(_base); } +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_register_view.cpp b/src/devices/pic/gui/pic_register_view.cpp new file mode 100644 index 0000000..ef7de9b --- /dev/null +++ b/src/devices/pic/gui/pic_register_view.cpp @@ -0,0 +1,329 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "pic_register_view.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qpopupmenu.h> + +#include <klocale.h> +#include <kiconloader.h> + +#include "libgui/main_global.h" +#include "devices/gui/hex_word_editor.h" +#include "common/gui/misc_gui.h" +#include "devices/pic/base/pic.h" +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_group.h" +#include "libgui/gui_debug_manager.h" +#include "coff/base/text_coff.h" + +//----------------------------------------------------------------------------- +Pic::BankWidget::BankWidget(uint i, QWidget *parent) + : QFrame(parent, "bank_widget"), _bindex(i), _bankCombo(0) +{ + setFrameStyle(WinPanel | Sunken); + QGridLayout *top = new QGridLayout(this, 1, 1, 5, 0); + top->setColSpacing(1, 4); + QFont f("courier", font().pointSize()); + + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + bool debugging = Main::programmerGroup().isDebugger(); + uint row = 0; + if ( rdata.nbBanks!=1 ) { + if ( data.is18Family() ) { + if ( (i/2)==0 ) { + QString title = ((i%2)==0 ? i18n("Access Bank (low)") : i18n("Access Bank (high)")); + QLabel *label = new QLabel(title, this); + label->setAlignment(AlignCenter); + top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter); + } else { + _bankCombo = new QComboBox(this); + for (uint k=1; k<2*rdata.nbBanks-1; k++) { + _bankCombo->insertItem((k%2)==0 ? i18n("Bank %1 (low)").arg(k/2) : i18n("Bank %1 (high)").arg(k/2)); + } + if ( _bindex==3 ) _bankCombo->setCurrentItem(1); + connect(_bankCombo, SIGNAL(activated(int)), SLOT(bankChanged())); + top->addMultiCellWidget(_bankCombo, row,row, 0,6, AlignHCenter); + } + } else { + QLabel *label = new QLabel(i18n("Bank %1").arg(i), this); + label->setAlignment(AlignCenter); + top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter); + } + row++; + top->setRowSpacing(row, 5); + row++; + } + + KIconLoader loader; + QPixmap readIcon = loader.loadIcon("viewmag", KIcon::Small); + QPixmap editIcon = loader.loadIcon("edit", KIcon::Small); + uint nb; + if ( !data.is18Family() ) nb = rdata.nbRegistersPerBank(); + else nb = kMax(rdata.accessBankSplit, rdata.nbRegistersPerBank() - rdata.accessBankSplit); + _registers.resize(nb); + for (uint k=0; k<nb; k++) { + _registers[k].alabel = new QLabel(this); + _registers[k].alabel->setFont(f); + top->addWidget(_registers[k].alabel, row, 0); + if (debugging) { + _registers[k].button = new PopupButton(this); + _registers[k].button->appendItem(i18n("Read"), readIcon, ReadId); + _registers[k].button->appendItem(i18n("Edit"), editIcon, EditId); + _registers[k].button->appendItem(i18n("Watch"), WatchId); + connect(_registers[k].button, SIGNAL(activated(int)), SLOT(buttonActivated(int))); + top->addWidget(_registers[k].button, row, 2); + _registers[k].edit = new Register::LineEdit(this); + connect(_registers[k].edit, SIGNAL(modified()), SLOT(write())); + _registers[k].edit->setFont(f); + top->addWidget(_registers[k].edit, row, 6); + } else { + _registers[k].label = new QLabel(this); + top->addWidget(_registers[k].label, row, 2); + } + row++; + } + + if (debugging) { + top->setColSpacing(3, 5); + top->setColSpacing(5, 5); + } + top->setRowStretch(row, 1); + + updateRegisterAddresses(); +} + +void Pic::BankWidget::bankChanged() +{ + updateRegisterAddresses(); + updateView(); +} + +uint Pic::BankWidget::bank() const +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + if ( !data.is18Family() ) return _bindex; + if ( _bindex==0 ) return 0; + const Pic::RegistersData &rdata = data.registersData(); + if ( _bindex==1 ) return rdata.nbBanks - 1; + return (_bankCombo->currentItem()+1)/2; +} + +uint Pic::BankWidget::nbRegisters() const +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + if ( !data.is18Family() ) return rdata.nbRegistersPerBank(); + if ( _bindex==0 || (_bankCombo && _bankCombo->currentItem()==2*int(rdata.nbBanks)-3) ) return rdata.accessBankSplit; + if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return rdata.nbRegistersPerBank() - rdata.accessBankSplit; + return rdata.nbRegistersPerBank() / 2; +} + +uint Pic::BankWidget::indexOffset() const +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + uint offset = bank() * rdata.nbRegistersPerBank(); + if ( !data.is18Family() ) return offset; + if ( _bindex==0 || (_bankCombo && (_bankCombo->currentItem()%2)==1) ) return offset; + if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return offset + rdata.accessBankSplit; + return offset + rdata.nbRegistersPerBank()/2; +} + +void Pic::BankWidget::updateRegisterAddresses() +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + uint nbChars = rdata.nbCharsAddress(); + uint nb = nbRegisters(); + uint offset = indexOffset(); + for (uint k=0; k<_registers.count(); k++) { + if ( k<nb ) { + _registers[k].alabel->show(); + _registers[k].address = rdata.addressFromIndex(offset + k); + _registers[k].alabel->setText(toHexLabel(_registers[k].address, nbChars) + ":"); + } else _registers[k].alabel->hide(); + } +} + +void Pic::BankWidget::buttonActivated(int id) +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; i<_registers.count(); i++) { + if ( sender()!=_registers[i].button ) continue; + Register::TypeData rtd(_registers[i].address, rdata.nbChars()); + switch (id) { + case ReadId: Debugger::manager->readRegister(rtd); break; + case EditId: + _registers[i].edit->selectAll(); + _registers[i].edit->setFocus(); + break; + case WatchId: { + bool isWatched = Register::list().isWatched(rtd); + Debugger::manager->setRegisterWatched(rtd, !isWatched); + break; + } + } + break; + } +} + +void Pic::BankWidget::write() +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; i<_registers.count(); i++) { + if ( sender()!=_registers[i].edit ) continue; + Register::TypeData rtd(_registers[i].address, rdata.nbChars()); + Debugger::manager->writeRegister(rtd, _registers[i].edit->value()); + break; + } +} + +void Pic::BankWidget::updateView() +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + bool active = ( Main::programmerState()==Programmer::Halted ); + const Coff::Object *coff = Debugger::manager->coff(); + uint nb = nbRegisters(); + for (uint i=0; i<_registers.count(); i++) { + uint address = _registers[i].address; + Device::RegisterProperties rp = rdata.properties(address); + QString label = rdata.label(address); + Register::TypeData rtd(address, rdata.nbChars()); + bool isWatched = Register::list().isWatched(rtd); + if (coff) { + QString name = coff->variableName(address); + if ( !name.isEmpty() ) label = "<" + name + ">"; + } + if (_registers[i].button) { + if ( i<nb ) { + _registers[i].button->show(); + _registers[i].button->setText(label); + if (isWatched) { + QFont f = _registers[i].button->font(); + f.setBold(true); + _registers[i].button->setFont(f); + } else _registers[i].button->unsetFont(); + _registers[i].button->popup()->setItemEnabled(ReadId, active && (rp & Device::Readable)); + _registers[i].button->popup()->setItemEnabled(EditId, active); + _registers[i].button->popup()->changeItem(WatchId, isWatched ? i18n("Stop Watching") : i18n("Watch")); + _registers[i].button->popup()->setItemEnabled(WatchId, rp & Device::Readable); + } else _registers[i].button->hide(); + } + if (_registers[i].label) { + if ( i<nb ) { + _registers[i].label->show(); + _registers[i].label->setText(label); + } else _registers[i].label->hide(); + } + if (_registers[i].edit) { + if ( i<nb ) { + _registers[i].edit->show(); + _registers[i].edit->setEnabled(active); + BitValue value = Register::list().value(rtd); + if ( value!=Register::list().oldValue(rtd) ) _registers[i].edit->setColor(red); + else _registers[i].edit->unsetColor(); + _registers[i].edit->setValue(NumberBase::Hex, value, rdata.nbChars()); + } else _registers[i].edit->hide(); + } + } +} + +//----------------------------------------------------------------------------- +Pic::RegisterView::RegisterView(QWidget *parent) + : Register::View(parent, "pic_register_view"), + _readAllButton(0), _clearAllButton(0) +{ + QVBoxLayout *vbox = new QVBoxLayout(this, 10, 10); + QHBoxLayout *hbox = new QHBoxLayout(vbox); + + bool debugging = Main::programmerGroup().isDebugger(); + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + uint nb = data.registersData().nbBanks; + if ( debugging && nb!=0 ) { + QWidget *w = new QWidget(this); + hbox->addWidget(w); + QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10); + _readAllButton = new QPushButton(i18n("Read All"), w); + connect(_readAllButton, SIGNAL(clicked()), Debugger::manager, SLOT(readAllRegisters())); + grid->addWidget(_readAllButton, 0, 0); + _clearAllButton = new QPushButton(i18n("Clear all watching"), w); + connect(_clearAllButton, SIGNAL(clicked()), SLOT(stopWatchAllRegisters())); + grid->addWidget(_clearAllButton, 0, 1); + grid->setColStretch(2, 1); + } + + QHBoxLayout *hbox2 = 0; + if ( nb==0 ) { + QLabel *label = new QLabel(i18n("Registers information not available."), this); + vbox->addWidget(label); + } else { + hbox = new QHBoxLayout(vbox); + hbox2 = new QHBoxLayout(hbox); + hbox->addStretch(1); + if ( data.is18Family() ) { + nb = 2; + for (uint k=1; k<data.registersData().nbBanks-1; k++) { + if ( !data.registersData().isBankUsed(k) ) continue; + nb += 2; + break; + } + } + _banks.resize(nb); + for (uint i=0; i<nb; i++) { + _banks[i] = new BankWidget(i, this); + _banks[i]->show(); + hbox2->addWidget(_banks[i]); + } + } + vbox->addStretch(1); +} + +void Pic::RegisterView::updateView() +{ + if (_readAllButton) _readAllButton->setEnabled(Main::programmerState()==Programmer::Halted); + for (uint i=0; i<_banks.count(); i++) if (_banks[i]) _banks[i]->updateView(); +} + +void Pic::RegisterView::stopWatchAllRegisters() +{ + Debugger::manager->stopWatchAll(); +} + +//---------------------------------------------------------------------------- +Pic::RegisterListViewItem::RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent) + : Register::ListViewItem(data, parent) +{} + +uint Pic::RegisterListViewItem::nbCharsAddress() const +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + return data.registersData().nbCharsAddress(); +} + +QString Pic::RegisterListViewItem::label() const +{ + if ( _data.type()!=Register::Regular ) return _data.name(); + const Coff::Object *coff = Debugger::manager->coff(); + if (coff) { + QString name = coff->variableName(_data.address()); + if ( !name.isEmpty() ) return "<" + name + ">"; + } + const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData()); + return data.registersData().label(_data.address()); +} diff --git a/src/devices/pic/gui/pic_register_view.h b/src/devices/pic/gui/pic_register_view.h new file mode 100644 index 0000000..f5b9d4b --- /dev/null +++ b/src/devices/pic/gui/pic_register_view.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef PIC_REGISTER_VIEW_H +#define PIC_REGISTER_VIEW_H + +#include <qvaluevector.h> +class QPushButton; +class QCheckBox; +class QLabel; +class QComboBox; + +#include "devices/gui/register_view.h" +#include "devices/pic/base/pic.h" +#include "devices/pic/base/pic_register.h" +class PopupButton; +namespace Device { class RegisterHexWordEditor; } + +namespace Pic +{ +//----------------------------------------------------------------------------- +class BankWidget : public QFrame +{ +Q_OBJECT +public: + BankWidget(uint bank, QWidget *parent); + void updateView(); + +private slots: + void buttonActivated(int id); + void write(); + void bankChanged(); + +private: + enum Id { ReadId, EditId, WatchId }; + class Data { + public: + Data() : label(0), button(0), edit(0) {} + uint address; + QLabel *alabel, *label; + PopupButton *button; + Register::LineEdit *edit; + }; + uint _bindex; + QComboBox *_bankCombo; + QValueVector<Data> _registers; + + uint bank() const; + uint nbRegisters() const; + uint indexOffset() const; + void updateRegisterAddresses(); +}; + +//----------------------------------------------------------------------------- +class RegisterView : public Register::View +{ +Q_OBJECT +public: + RegisterView(QWidget *parent); + virtual void updateView(); + +private slots: + void stopWatchAllRegisters(); + +private: + QPushButton *_readAllButton, *_clearAllButton; + QValueVector<BankWidget *> _banks; +}; + +//----------------------------------------------------------------------------- +class RegisterListViewItem : public Register::ListViewItem +{ +public: + RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent); + +private: + virtual uint nbCharsAddress() const; + virtual QString label() const; +}; + +} // namespace + +#endif |