/*************************************************************************** * Copyright (C) 2005-2007 Nicolas Hadacek * * Copyright (C) 2003-2004 Alain Gibaud * * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #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 TQString &text, TQWidget *parent) { button = new PopupButton(text, parent); KActionCollection *ac = 0; KAction *a = new KAction(i18n("Go to start"), "top", 0, TQT_TQOBJECT(parent), TQT_SLOT(gotoStart()), ac); actions.append(a); button->appendAction(a); a = new KAction(i18n("Go to end"), "bottom", 0, TQT_TQOBJECT(parent), TQT_SLOT(gotoEnd()), ac); actions.append(a); button->appendAction(a); label = new TQLabel(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; isetFixedWidth(20); w->setPaletteBackgroundColor(protectedColor()); grid->addWidget(w, 0, 0); const Protection &protection = device().config().protection(); TQString s = (protection.family()==Protection::CodeGuard ? i18n("High Security") : i18n("Code protection")); TQLabel *label = new TQLabel(s, this); grid->addMultiCellWidget(label, 0,0, 1,2); grid->addRowSpacing(1, 10); uint row = 2; if ( type==MemoryRangeType::Code && protection.hasBootBlock() ) { w = new TQWidget(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; isetFixedWidth(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(TQString("[%1:%2]").tqarg(toHex(r.start, nbChars)).tqarg(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(TQString("[%1:%2]").tqarg(toHex(r.start, nbChars)).tqarg(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(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(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, TQWidget *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, TQWidget *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(TQVBoxLayout *vbox) { if ( type()==MemoryRangeType::Code || type()==MemoryRangeType::Eeprom ) { _legend = new MemoryEditorLegend(type(), memory(), this); connect(_legend, TQT_SIGNAL(setStartWord(int)), TQT_SLOT(setStartWord(int))); connect(_legend, TQT_SIGNAL(setEndWord(int)), TQT_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(TQWidget *parent) { return new HexWordEditor(type(), memory(), parent); } //----------------------------------------------------------------------------- Pic::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, TQWidget *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()); TQString add; if ( type()==MemoryRangeType::UserId ) add = i18n(" - recommended mask: %1").tqarg(toHexLabel(device().userIdRecommendedMask(), nbChars)); if ( type()==MemoryRangeType::Cal && _hexview ) add = i18n(" - not programmed by default"); TQString comment = i18n("%1-bit words - mask: %2") .tqarg(device().nbBitsWord(type())).tqarg(toHexLabel(device().mask(type()), nbChars)); _comment->setText(comment + add); } bool Pic::MemoryTypeEditor::internalDoAction(Device::Action action) { Programmer::PicBase *prog = static_cast(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(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, TQWidget *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, TQWidget *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, TQT_TQOBJECT(this), TQT_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(TQString()); 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, TQWidget *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(Main::programmer()); switch (action) { case Device::Reload: { const Memory *omemory = static_cast(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; }