diff options
Diffstat (limited to 'src/progs')
277 files changed, 21103 insertions, 0 deletions
diff --git a/src/progs/Makefile.am b/src/progs/Makefile.am new file mode 100644 index 0000000..634b7d1 --- /dev/null +++ b/src/progs/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = base gui direct icd2 icd1 pickit2 pickit1 pickit2v2 psp gpsim \ + bootloader picdem_bootloader tbl_bootloader pickit2_bootloader list manager
\ No newline at end of file diff --git a/src/progs/base/Makefile.am b/src/progs/base/Makefile.am new file mode 100644 index 0000000..c045428 --- /dev/null +++ b/src/progs/base/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + + +libprogbase_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogbase.la +libprogbase_la_SOURCES = generic_prog.cpp prog_specific.cpp prog_config.cpp \ + prog_group.cpp generic_debug.cpp hardware_config.cpp debug_config.cpp + + diff --git a/src/progs/base/base.pro b/src/progs/base/base.pro new file mode 100644 index 0000000..b2556e4 --- /dev/null +++ b/src/progs/base/base.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progbase +HEADERS += generic_prog.h generic_debug.h prog_config.h prog_group.h prog_specific.h \ + hardware_config.h debug_config.h +SOURCES += generic_prog.cpp generic_debug.cpp prog_config.cpp prog_group.cpp prog_specific.cpp \ + hardware_config.cpp debug_config.cpp diff --git a/src/progs/base/debug_config.cpp b/src/progs/base/debug_config.cpp new file mode 100644 index 0000000..387941d --- /dev/null +++ b/src/progs/base/debug_config.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "debug_config.h" + +const Debugger::Config::Data Debugger::Config::DATA[Nb_Types] = { + { "only_stop_on_source_line", I18N_NOOP("Only stop stepping on source line."), QVariant(true, 0) }, + { "only_stop_on_project_source_line", I18N_NOOP("Only stop stepping on project source line."), QVariant(true, 0) } +}; diff --git a/src/progs/base/debug_config.h b/src/progs/base/debug_config.h new file mode 100644 index 0000000..acd7f09 --- /dev/null +++ b/src/progs/base/debug_config.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2007 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 DEBUG_CONFIG_H +#define DEBUG_CONFIG_H + +#include "common/global/generic_config.h" +#include "common/common/key_enum.h" + +namespace Debugger +{ + +BEGIN_DECLARE_CONFIG(Config) + OnlyStopOnSourceLine, OnlyStopOnProjectSourceLine +END_DECLARE_CONFIG(Config, "debugger") + +} // namespace + +#endif diff --git a/src/progs/base/generic_debug.cpp b/src/progs/base/generic_debug.cpp new file mode 100644 index 0000000..252d239 --- /dev/null +++ b/src/progs/base/generic_debug.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * 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 "generic_debug.h" + +#include "common/global/global.h" +#include "generic_prog.h" +#include "devices/base/register.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//---------------------------------------------------------------------------- +Debugger::Base::Base(Programmer::Base &programmer) + : Log::Base(&programmer), _programmer(programmer), _deviceSpecific(0), + _specific(0), _inputType(PURL::Nb_FileTypes), _coff(0) +{} + +void Debugger::Base::init(DeviceSpecific *deviceSpecific, Specific *specific) +{ + _deviceSpecific = deviceSpecific; + _specific = specific; +} + +Debugger::Base::~Base() +{ + delete _deviceSpecific; + delete _specific; +} + +const Device::Data *Debugger::Base::device() const +{ + return _programmer.device(); +} + +bool Debugger::Base::init() +{ + _programmer.setState(Programmer::Stopped); + log(Log::LineType::Information, i18n("Setting up debugging session.")); + if ( !internalInit() ) { + log(Log::LineType::Error, i18n("Failed to initialize device for debugging.")); + return false; + } + log(Log::LineType::Information, i18n("Ready to start debugging.")); + _programmer.setState(Programmer::Halted); + return update(); +} + +bool Debugger::Base::update() +{ + if ( !updateState() ) return false; + if ( _programmer.state()==::Programmer::Halted ) return _deviceSpecific->updateStatus(); + return true; +} + +bool Debugger::Base::run() +{ + if ( !internalRun() ) return false; + _programmer.setState(::Programmer::Running); + return update(); +} + +bool Debugger::Base::step() +{ + if ( !internalStep() ) return false; + return update(); +} + +bool Debugger::Base::halt() +{ + bool success; + if ( !softHalt(success) ) return false; + if ( !success ) return hardHalt(); + if ( !update() ) return false; + log(Log::LineType::Information, QString("Halted at %1").arg(toHexLabel(pc(), _programmer.device()->nbCharsAddress()))); + _programmer.setState(::Programmer::Halted); + return true; +} + +bool Debugger::Base::reset() +{ + if ( !internalReset() ) return false; + return update(); +} + +QString Debugger::Base::statusString() const +{ + if ( _programmer.state()!=::Programmer::Halted ) return QString::null; + return _deviceSpecific->statusString(); +} + +void Debugger::Base::setupInput(PURL::FileType type, const QString &directory, const QString &filename) +{ + _inputType = type; + _directory = directory; + _filename = filename; +} + +BitValue Debugger::Base::pc() const +{ + return Register::list().value(pcTypeData()); +} + +Register::TypeData Debugger::Base::pcTypeData() const +{ + return Register::TypeData("PC", 2*device()->nbBytesAddress()); +} diff --git a/src/progs/base/generic_debug.h b/src/progs/base/generic_debug.h new file mode 100644 index 0000000..903d451 --- /dev/null +++ b/src/progs/base/generic_debug.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * 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 GENERIC_DEBUG_H +#define GENERIC_DEBUG_H + +#include "common/common/purl_base.h" +#include "common/global/global.h" +#include "common/global/log.h" +#include "devices/base/register.h" +namespace Programmer { class Base; } +namespace Coff { class TextObject; } + +namespace Debugger +{ +class DeviceSpecific; +class Specific; + +//---------------------------------------------------------------------------- +class Base : public Log::Base +{ +public: + Base(Programmer::Base &programmer); + virtual ~Base(); + void init(DeviceSpecific *deviceSpecific, Specific *specific); + const Device::Data *device() const; + void setupInput(PURL::FileType type, const QString &directory, const QString &filename); + void setCoff(const Coff::TextObject *coff) { _coff = coff; } + QString directory() const { return _directory; } + bool init(); + bool update(); + bool reset(); + bool run(); + bool halt(); + bool step(); + QString statusString() const; + virtual bool setBreakpoints(const QValueList<Address> &addresses) = 0; + BitValue pc() const; + Register::TypeData pcTypeData() const; + virtual bool readRegister(const Register::TypeData &data, BitValue &value) = 0; + virtual bool writeRegister(const Register::TypeData &data, BitValue value) = 0; + virtual bool updatePortStatus(uint index, QMap<uint, Device::PortBitData> &bits) = 0; + +protected: + Programmer::Base &_programmer; + DeviceSpecific *_deviceSpecific; + Specific *_specific; + PURL::FileType _inputType; + QString _directory, _filename; + const Coff::TextObject *_coff; + + virtual bool internalInit() = 0; + virtual bool internalRun() = 0; + virtual bool softHalt(bool &success) = 0; + virtual bool hardHalt() = 0; + virtual bool internalStep() = 0; + virtual bool internalReset() = 0; + virtual bool updateState() = 0; +}; + +//---------------------------------------------------------------------------- +class DeviceSpecific : public Log::Base +{ +public: + DeviceSpecific(Debugger::Base &base) : Log::Base(base), _base(base) {} + virtual bool updateStatus() = 0; + virtual QString statusString() const = 0; + +protected: + Debugger::Base &_base; +}; + +//---------------------------------------------------------------------------- +class Specific : public Log::Base +{ +public: + Specific(Debugger::Base &base) : Log::Base(base), _base(base) {} + +protected: + Debugger::Base &_base; +}; + +} // namespace + +#endif diff --git a/src/progs/base/generic_prog.cpp b/src/progs/base/generic_prog.cpp new file mode 100644 index 0000000..6386eb2 --- /dev/null +++ b/src/progs/base/generic_prog.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 "generic_prog.h" + +#include <qdir.h> + +#include "common/global/global.h" +#include "prog_group.h" +#include "prog_config.h" +#include "devices/base/device_group.h" +#include "generic_debug.h" +#include "hardware_config.h" + +//----------------------------------------------------------------------------- +const double Programmer::UNKNOWN_VOLTAGE = -1.0; + +const char * const Programmer::RESULT_TYPE_LABELS[Nb_ResultTypes+1] = { + I18N_NOOP("Pass"), + I18N_NOOP("Low"), + I18N_NOOP("High"), + I18N_NOOP("Fail"), + I18N_NOOP("---") +}; + +const Programmer::Task::Data Programmer::Task::DATA[Nb_Types] = { + { 0, I18N_NOOP("Reading...") }, + { 0, I18N_NOOP("Programming...") }, + { 0, I18N_NOOP("Verifying...") }, + { 0, I18N_NOOP("Erasing...") }, + { 0, I18N_NOOP("Blank Checking...") } +}; + +//----------------------------------------------------------------------------- +Programmer::Base::Base(const Group &group, const Device::Data *device, const char *) + : _hardware(0), _specific(0), _device(device), _debugger(group.createDebugger(*this)), + _state(NotConnected), _targetPowerOn(false), _group(group) +{} + +void Programmer::Base::init(bool targetSelfPowered, Hardware *hardware, DeviceSpecific *ds) +{ + clear(); + _targetSelfPowered = targetSelfPowered; + _hardware = hardware; + _specific = ds; +} + +Programmer::Base::~Base() +{ + delete _debugger; + delete _specific; + delete _hardware; +} + +void Programmer::Base::clear() +{ + _firmwareVersion.clear(); + _mode = NormalMode; + resetError(); +} + +bool Programmer::Base::simpleConnectHardware() +{ + Q_ASSERT(_hardware); + disconnectHardware(); + clear(); + if (_device) { + QString label = _group.label(); + if ( group().isSoftware() ) + log(Log::LineType::Information, i18n("Connecting %1 with device %2...").arg(label).arg(_device->name())); + else { + if ( !_hardware->name().isEmpty() ) label += "[" + _hardware->name() + "]"; + Port::Description pd = _hardware->portDescription(); + QString s = pd.type.label(); + if (pd.type.data().withDevice) s += " (" + pd.device + ")"; + log(Log::LineType::Information, i18n("Connecting %1 on %2 with device %3...").arg(label).arg(s).arg(_device->name())); + } + } + return _hardware->connectHardware(); +} + +bool Programmer::Base::connectHardware() +{ + _progressMonitor.insertTask(i18n("Connecting..."), 2); + log(Log::DebugLevel::Extra, "connect hardware"); + if ( !simpleConnectHardware() ) return false; + _progressMonitor.addTaskProgress(1); + if ( !group().isSoftware() ) { + if ( !readFirmwareVersion() ) return false; + if ( _specific==0 ) return true; + if ( _mode==BootloadMode ) return true; + if ( !setupFirmware() ) return false; + if ( !checkFirmwareVersion() ) return false; + if ( !setTargetPowerOn(false) ) return false; + if ( !setTarget() ) return false; + log(Log::LineType::Information, i18n(" Set target self powered: %1").arg(_targetSelfPowered ? "true" : "false")); + if ( !setTargetPowerOn(!_targetSelfPowered) ) return false; + if ( !internalSetupHardware() ) return false; + if ( !readVoltages() ) return false; + if ( !selfTest(true) ) return false; + } + if ( hasError() ) return false; + log(Log::LineType::Information, i18n("Connected.")); + _state = Stopped; + return true; +} + +void Programmer::Base::disconnectHardware() +{ + _state = NotConnected; + log(Log::DebugLevel::Extra, "disconnect hardware"); + clear(); + _hardware->disconnectHardware(); +} + +PURL::Directory Programmer::Base::firmwareDirectory() +{ + if ( _firmwareDirectory.isEmpty() ) _firmwareDirectory = GroupConfig::firmwareDirectory(group()); + PURL::Directory dir(_firmwareDirectory); + if ( !dir.exists() ) { + log(Log::LineType::Error, i18n("Firmware directory is not configured or does not exist.")); + return PURL::Directory(); + } + return dir; +} + +bool Programmer::Base::checkFirmwareVersion() +{ + if ( _mode==BootloadMode ) log(Log::LineType::Information, i18n("Programmer is in bootload mode.")); + if ( !_firmwareVersion.isValid() ) return true; + log(Log::LineType::Information, i18n("Firmware version is %1").arg(_firmwareVersion.pretty())); + VersionData vd = _firmwareVersion.toWithoutDot(); + VersionData tmp = firmwareVersion(FirmwareVersionType::Max); + if ( tmp.isValid() && tmp.toWithoutDot()<vd ) { + VersionData mplab = mplabVersion(FirmwareVersionType::Max); + QString s = (mplab.isValid() ? " " + i18n("MPLAB %1").arg(mplab.prettyWithoutDot()) : QString::null); + log(Log::LineType::Warning, i18n("The firmware version (%1) is higher than the version tested with piklab (%2%3).\n" + "You may experience problems.").arg(_firmwareVersion.pretty()).arg(tmp.pretty()).arg(s)); + return true; + } + tmp = firmwareVersion(FirmwareVersionType::Min); + if ( tmp.isValid() && vd<tmp.toWithoutDot() ) { + VersionData mplab = mplabVersion(FirmwareVersionType::Min); + QString s = (mplab.isValid() ? " " + i18n("MPLAB %1").arg(mplab.prettyWithoutDot()) : QString::null); + log(Log::LineType::Warning, i18n("The firmware version (%1) is lower than the version tested with piklab (%2%3).\n" + "You may experience problems.").arg(_firmwareVersion.pretty()).arg(tmp.pretty()).arg(s)); + return true; + } + tmp = firmwareVersion(FirmwareVersionType::Recommended); + if ( tmp.isValid() && vd<tmp.toWithoutDot() ) { + VersionData mplab = mplabVersion(FirmwareVersionType::Recommended); + QString s = (mplab.isValid() ? " " + i18n("MPLAB %1").arg(mplab.prettyWithoutDot()) : QString::null); + log(Log::LineType::Warning, i18n("The firmware version (%1) is lower than the recommended version (%2%3).\n" + "It is recommended to upgrade the firmware.").arg(_firmwareVersion.pretty()).arg(tmp.pretty()).arg(s)); + return true; + } + return true; +} + +bool Programmer::Base::enterMode(Mode mode) +{ + log(Log::DebugLevel::Normal, mode==BootloadMode ? " Enter bootload mode" : " Enter normal mode"); + if ( _mode==mode ) { + log(Log::DebugLevel::Normal, " Already in requested mode."); + return true; + } + if ( !internalEnterMode(mode) ) return false; + return ( _mode==mode ); +} + +void Programmer::Base::log(Log::LineType type, const QString &message) +{ + if ( type==Log::LineType::Error ) _state = NotConnected; + Log::Base::log(type, message); +} + +void Programmer::Base::log(Log::DebugLevel level, const QString &message) +{ + Log::Base::log(level, message); +} + +bool Programmer::Base::setTargetPowerOn(bool on) +{ + _targetPowerOn = on; + return _specific->setTargetPowerOn(on); +} + +void Programmer::Base::appendTask(Task task, const Device::MemoryRange *range) +{ + _progressMonitor.appendTask(task.label(), nbSteps(task, range)); +} + +bool Programmer::Base::connectDevice() +{ + _progressMonitor.clear(); + bool ok = doConnectDevice(); + endProgramming(); + return ok; +} + +bool Programmer::Base::doConnectDevice() +{ + if ( _state==NotConnected ) { + if ( !connectHardware() ) return false; + if ( !enterMode(NormalMode) ) return false; + if ( !verifyDeviceId() ) return false; + } else { + setTargetPowerOn(!_targetSelfPowered); + } + _state = Stopped; + return true; +} + +bool Programmer::Base::run() +{ + emit actionMessage(i18n("Running...")); + _progressMonitor.clear(); + if ( !doConnectDevice() ) return false; + log(Log::LineType::Information, i18n("Run...")); + internalRun(); + return !hasError(); +} + +bool Programmer::Base::stop() +{ + emit actionMessage(i18n("Breaking...")); + return internalStop(); +} + +void Programmer::Base::endProgramming() +{ + if ( _state==Stopped && readConfigEntry(Config::PowerDownAfterProgramming).toBool() ) + setTargetPowerOn(false); + if ( !(group().properties() & HasConnectedState) ) disconnectHardware(); + _progressMonitor.clear(); +} + +bool Programmer::Base::uploadFirmware(const PURL::Url &url) +{ + _progressMonitor.clear(); + log(Log::DebugLevel::Normal, QString(" Firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + bool ok = doUploadFirmware(file); + _firmwareVersion.clear(); + if (ok) ok = readFirmwareVersion(); + endProgramming(); + return ok; +} + +bool Programmer::Base::doUploadFirmware(PURL::File &file) +{ + emit actionMessage(i18n("Uploading firmware...")); + return internalUploadFirmware(file); +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::erase(const Device::MemoryRange &range) +{ + _progressMonitor.clear(); + appendTask(Task::Erase, &range); + if ( readConfigEntry(Config::BlankCheckAfterErase).toBool() ) appendTask(Task::BlankCheck); + bool ok = doErase(range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doErase(const Device::MemoryRange &range) +{ + if ( !checkErase() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Erasing...")); + if ( !internalErase(range) ) return false; + log(Log::LineType::Information, i18n("Erasing done")); + if ( readConfigEntry(Config::BlankCheckAfterErase).toBool() ) { + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Blank checking...")); + if ( !doVerify(BlankCheckVerify, range, 0) ) return false; + log(Log::LineType::Information, i18n("Blank checking done.")); + } + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::checkCanRead() +{ + if ( !(group().properties() & CanReadMemory) ) { + log(Log::LineType::Error, i18n("The selected programmer cannot read device memory.")); + return false; + } + return true; +} + +bool Programmer::Base::read(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::Read, &range); + bool ok = doRead(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doRead(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Reading device memory...")); + memory.clear(); + if ( !internalRead(&memory, range, 0) ) return false; + log(Log::LineType::Information, i18n("Reading done.")); + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::program(const Device::Memory &memory, const Device::MemoryRange &range) +{ + _progressMonitor.clear(); + appendTask(Task::Write, &range); + bool ok = doProgram(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doProgram(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkProgram(memory) ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Programming device memory...")); + if ( !internalProgram(memory, range) ) return false; + log(Log::LineType::Information, i18n("Programming successful.")); + if ( group().isDebugger() && !_debugger->init() ) return false; + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::verify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::Verify, &range); + bool ok = doVerify(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doVerify(VerifyAction action, const Device::MemoryRange &range, const Device::Memory *memory) +{ + const Device::Memory *vmemory = memory; + if ( memory==0 ) { + Q_ASSERT( action & BlankCheckVerify ); + vmemory = _device->group().createMemory(*_device); + } + VerifyData vdata(action, *vmemory); + bool ok = internalRead(0, range, &vdata); + if ( memory==0 ) delete vmemory; + return ok; +} + +bool Programmer::Base::doVerify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Verifying...")); + if ( !doVerify(NormalVerify, range, &memory) ) return false; + log(Log::LineType::Information, i18n("Verifying successful.")); + return true; +} + +bool Programmer::Base::blankCheck(const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::BlankCheck, &range); + bool ok = doBlankCheck(range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doBlankCheck(const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Blank checking...")); + if ( !doVerify(BlankCheckVerify, range, 0) ) return false; + log(Log::LineType::Information, i18n("Blank checking successful.")); + return true; +} diff --git a/src/progs/base/generic_prog.h b/src/progs/base/generic_prog.h new file mode 100644 index 0000000..3b4b219 --- /dev/null +++ b/src/progs/base/generic_prog.h @@ -0,0 +1,163 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef GENERIC_PROG_H +#define GENERIC_PROG_H + +#include "common/global/log.h" +#include "common/global/pfile.h" +#include "common/common/version_data.h" +#include "common/port/port_base.h" +#include "common/global/progress_monitor.h" +#include "devices/base/generic_device.h" +#include "devices/base/generic_memory.h" +#include "prog_specific.h" +namespace Debugger { class Base; } +namespace Device { class MemoryRange; } + +namespace Programmer +{ + enum Mode { NormalMode, BootloadMode }; + enum State { NotConnected = 0, Stopped, Running, Halted }; + class Hardware; + class Group; + class DeviceSpecific; + extern const double UNKNOWN_VOLTAGE; + + enum VerifyAction { NormalVerify = 0, BlankCheckVerify = 1, + IgnoreProtectedVerify = 2, OnlyProgrammedVerify = 4 }; + Q_DECLARE_FLAGS(VerifyActions, VerifyAction) + Q_DECLARE_OPERATORS_FOR_FLAGS(VerifyActions) + class VerifyData { + public: + VerifyData(VerifyActions pactions, const Device::Memory &pmemory) : actions(pactions), memory(pmemory) {} + VerifyActions actions; + AddressRangeVector protectedRanges; + const Device::Memory &memory; + }; + + enum ResultType { Pass = 0, Low, High, Fail, Nb_ResultTypes }; + extern const char * const RESULT_TYPE_LABELS[Nb_ResultTypes+1]; + + class HardwareDescription { + public: + Port::Description port; + QString name; + }; + + BEGIN_DECLARE_ENUM(Task) + Read = 0, Write, Verify, Erase, BlankCheck + END_DECLARE_ENUM_STD(Task) + + BEGIN_DECLARE_ENUM(FirmwareVersionType) + Min, Max, Recommended + END_DECLARE_ENUM_NO_DATA(FirmwareVersionType) + +//----------------------------------------------------------------------------- +class Base : public QObject, public Log::Base +{ +Q_OBJECT +public: + Base(const Group &group, const Device::Data *data, const char *name); + virtual ~Base(); + + virtual void log(Log::LineType type, const QString &message); + virtual void log(Log::DebugLevel level, const QString &message); + void init(bool targetSelfPowered, Hardware *hardware, DeviceSpecific *deviceSpecific); + const Device::Data *device() const { return _device; } + const Group &group() const { return _group; } + Hardware *hardware() { return _hardware; } + ProgressMonitor &progressMonitor() { return _progressMonitor; } + ::Debugger::Base *debugger() { return _debugger; } + virtual uint maxNbBreakpoints() const { return 1; } + virtual uint runUpdateWait() const { return 300; } + + bool simpleConnectHardware(); + bool connectHardware(); + void disconnectHardware(); + bool connectDevice(); + bool setTargetPowerOn(bool on); + bool isTargetPowerOn() const { return _targetPowerOn; } + bool isTargetSelfPowered() const { return _targetSelfPowered; } + void setFirmwareDirectory(const PURL::Directory &dir) { _firmwareDirectory = dir; } + const VersionData &firmwareVersion() const { return _firmwareVersion; } + virtual bool readFirmwareVersion() { return true; } + bool uploadFirmware(const PURL::Url &url); + virtual bool readVoltages() { return true; } + virtual bool selfTest(bool ask) { Q_UNUSED(ask); return true; } + void appendTask(Task task, const Device::MemoryRange *range = 0); + + bool erase(const Device::MemoryRange &range); + bool read(Device::Memory &memory, const Device::MemoryRange &range); + bool program(const Device::Memory &memory, const Device::MemoryRange &range); + bool verify(const Device::Memory &memory, const Device::MemoryRange &range); + bool blankCheck(const Device::MemoryRange &range); + bool run(); + bool stop(); + State state() const { return _state; } + void setState(State state) { _state = state; } + bool isConnected() const { return ( _state!=NotConnected ); } + bool isActive() const { return ( _state==Halted || _state==Running ); } + bool enterMode(Mode mode); + bool doConnectDevice(); + virtual void clear(); + +signals: + void actionMessage(const QString &message); + +protected: + Hardware *_hardware; + DeviceSpecific *_specific; + const Device::Data *_device; + ::Debugger::Base *_debugger; + State _state; + bool _targetPowerOn; + const Group &_group; + PURL::Directory _firmwareDirectory; + VersionData _firmwareVersion; + Mode _mode; + bool _targetSelfPowered; + ProgressMonitor _progressMonitor; + + PURL::Directory firmwareDirectory(); + virtual bool setupFirmware() { return true; } + virtual VersionData firmwareVersion(FirmwareVersionType type) const { Q_UNUSED(type); return VersionData(); } + virtual VersionData mplabVersion(FirmwareVersionType type) const { Q_UNUSED(type); return VersionData(); } + virtual bool checkFirmwareVersion(); + virtual bool setTarget() { return true; } + virtual bool internalSetupHardware() { return true; } + virtual bool verifyDeviceId() = 0; + virtual uint nbSteps(Task task, const Device::MemoryRange *range) const = 0; + virtual bool doUploadFirmware(PURL::File &); + virtual bool internalUploadFirmware(PURL::File &) { return false; } + virtual bool internalEnterMode(Mode) { return false; } + + virtual bool checkErase() = 0; + virtual bool internalErase(const Device::MemoryRange &range) = 0; + bool checkCanRead(); + virtual bool checkRead() = 0; + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const VerifyData *vdata) = 0; + virtual bool checkProgram(const Device::Memory &memory) = 0; + virtual bool internalProgram(const Device::Memory &memory, const Device::MemoryRange &range) = 0; + virtual bool internalRun() { return false; } + virtual bool internalStop() { return false; } + + void endProgramming(); + bool doErase(const Device::MemoryRange &range); + bool doRead(Device::Memory &memory, const Device::MemoryRange &range); + bool doVerify(const Device::Memory &memory, const Device::MemoryRange &range); + bool doVerify(VerifyAction action, const Device::MemoryRange &range, const Device::Memory *memory); + bool doBlankCheck(const Device::MemoryRange &range); + virtual bool doProgram(const Device::Memory &memory, const Device::MemoryRange &range); + + friend class DeviceSpecific; +}; + +} // namespace + +#endif diff --git a/src/progs/base/hardware_config.cpp b/src/progs/base/hardware_config.cpp new file mode 100644 index 0000000..5a3af7c --- /dev/null +++ b/src/progs/base/hardware_config.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 "hardware_config.h" + +//----------------------------------------------------------------------------- +bool Hardware::Data::isEqual(const Data &data) const +{ + return ( data.portType==portType ); +} + +void Hardware::Data::readConfig(GenericConfig &config) +{ + portType = config.readEnumEntry<PortType>("port_type", PortType::Serial); +} + +void Hardware::Data::writeConfig(GenericConfig &config) const +{ + config.writeEnumEntry<PortType>("port_type", portType); +} + +//----------------------------------------------------------------------------- +void Hardware::Config::writeCurrentHardware(PortType type, const QString &name) +{ + writeEntry(QString("current_hardware_") + type.key(), name); +} + +QString Hardware::Config::currentHardware(PortType type) +{ + QStringList names = hardwareNames(type); + return readEntry(QString("current_hardware_") + type.key(), names[0]); +} + +QString Hardware::Config::label(const QString &name) const +{ + const DataInfo *info = standardHardwareDataInfo(name); + if ( info==0 ) return QString::null; + return i18n(info->label); +} + +QString Hardware::Config::comment(const QString &name) const +{ + const DataInfo *info = standardHardwareDataInfo(name); + if ( info==0 || info->comment==0 ) return QString::null; + return i18n(info->comment); +} + +void Hardware::Config::writeCustomHardware(const QString& name, const Hardware::Data &hdata) +{ + Q_ASSERT( !isStandardHardware(name) ); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + if ( !customNames.contains(name) ) { + customNames += name; + writeEntry("custom_hardware_names", customNames); + } + GenericConfig config(group() + "_custom_hardware_" + name); + hdata.writeConfig(config); +} + +void Hardware::Config::deleteCustomHardware(const QString &name) +{ + Q_ASSERT( !isStandardHardware(name) ); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + customNames.remove(name); + writeEntry("custom_hardware_names", customNames); + GenericConfig::deleteGroup(group() + "_custom_hardware_" + name); +} + +Hardware::Data *Hardware::Config::hardwareData(const QString &name) const +{ + if ( isStandardHardware(name) ) return standardHardwareData(name); + Hardware::Data *hdata = createHardwareData(); + hdata->name = name; + GenericConfig config(group() + "_custom_hardware_" + name); + hdata->readConfig(config); + return hdata; +} + +QStringList Hardware::Config::hardwareNames(PortType type) +{ + QStringList names = standardHardwareNames(type); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + for (uint i=0; i<uint(customNames.count()); i++) { + if ( type!=PortType::Nb_Types ) { + Hardware::Data *hdata = hardwareData(customNames[i]); + if ( hdata->portType==type ) names += customNames[i]; + delete hdata; + } else names += customNames[i]; + } + return names; +} diff --git a/src/progs/base/hardware_config.h b/src/progs/base/hardware_config.h new file mode 100644 index 0000000..5252ff3 --- /dev/null +++ b/src/progs/base/hardware_config.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +#include "common/global/generic_config.h" +#include "common/port/port.h" + +namespace Hardware +{ +//----------------------------------------------------------------------------- +struct DataInfo +{ + const char *name, *label, *comment; +}; + +class Data +{ +public: + Data() : portType(PortType::Nb_Types) {} + virtual ~Data() {} + virtual void readConfig(GenericConfig &config); + virtual void writeConfig(GenericConfig &config) const; + virtual bool isEqual(const Data &data) const; + PortType portType; + QString name; +}; + +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + Config(const char *group) : GenericConfig(group) {} + virtual ~Config() {} + QStringList hardwareNames(PortType type); + bool isStandardHardware(const QString &name) const { return standardHardwareData(name); } + QString label(const QString &name) const; + QString comment(const QString &name) const; + void writeCustomHardware(const QString &name, const Hardware::Data &data); + QString currentHardware(PortType type); + void writeCurrentHardware(PortType type, const QString &name); + void deleteCustomHardware(const QString &name); + Hardware::Data *hardwareData(const QString& name) const; + +protected: + virtual QStringList standardHardwareNames(PortType type) const = 0; + virtual Hardware::Data *standardHardwareData(const QString &name) const = 0; + virtual const DataInfo *standardHardwareDataInfo(const QString &name) const = 0; + virtual Hardware::Data *createHardwareData() const = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/base/prog_config.cpp b/src/progs/base/prog_config.cpp new file mode 100644 index 0000000..8115ce7 --- /dev/null +++ b/src/progs/base/prog_config.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * 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 "prog_config.h" + +//---------------------------------------------------------------------------- +PortType Programmer::GroupConfig::portType(const Group &group) +{ + GenericConfig config(group.name()); + PortType ctype = config.readEnumEntry<PortType>("port_group"); + if ( group.isPortSupported(ctype) ) return ctype; + FOR_EACH(PortType, type) if ( group.isPortSupported(type) ) return type; + return PortType::Nb_Types; +} +void Programmer::GroupConfig::writePortType(const Group &group, PortType type) +{ + if ( type==PortType::Nb_Types ) return; + GenericConfig config(group.name()); + config.writeEnumEntry<PortType>("port_group", type); +} + +QString Programmer::GroupConfig::portDevice(const Group &group, PortType portType) +{ + GenericConfig config(group.name()); + QString device = config.readEntry(QString(portType.key()) + "_port_device" , QString::null); + if ( device.isNull() ) { + QStringList list = Port::probedDeviceList(portType); + if ( list.isEmpty() ) return QString::null; + return list[0]; + } + return device; +} +void Programmer::GroupConfig::writePortDevice(const Group &group, PortType type, const QString &device) +{ + if ( type==PortType::Nb_Types ) return; + GenericConfig config(group.name()); + config.writeEntry(QString(type.key()) + "_port_device", device); +} + +Port::Description Programmer::GroupConfig::portDescription(const Group &group) +{ + PortType type = portType(group); + return Port::Description(type, portDevice(group, type)); +} +void Programmer::GroupConfig::writePortDescription(const Group &group, const Port::Description &dp) +{ + writePortType(group, dp.type); + writePortDevice(group, dp.type, dp.device); +} + +QString Programmer::GroupConfig::firmwareDirectory(const Group &group) +{ + GenericConfig config(group.name()); + return config.readEntry("firmware_directory", QString::null); +} +void Programmer::GroupConfig::writeFirmwareDirectory(const Group &group, const QString &path) +{ + GenericConfig config(group.name()); + config.writeEntry("firmware_directory", path); +} + +//---------------------------------------------------------------------------- +const Programmer::Config::Data Programmer::Config::DATA[Nb_Types] = { + { "only_program_non_mask", I18N_NOOP("Only program what is needed (faster)."), QVariant(true, 0) }, + { "verify_after_program", I18N_NOOP("Verify device memory after programming."), QVariant(true, 0) }, + { "only_verify_programmed", I18N_NOOP("Only verify programmed words in code memory (faster)."), QVariant(true, 0) }, + { "power_down_after_programming", I18N_NOOP("Power down target after programming."), QVariant(true, 0) }, + { "target_self_powered", I18N_NOOP("Target is self-powered (when possible)."), QVariant(true, 0) }, + { "blank_check_after_erase", I18N_NOOP("Blank check after erase."), QVariant(false, 0) }, + { "preserve_eeprom", I18N_NOOP("Preserve data EEPROM when programming."), QVariant(false, 0) }, + { "program_eeprom", I18N_NOOP("Program data EEPROM."), QVariant(true, 0) }, + { "run_after_program", I18N_NOOP("Run device after successful programming."), QVariant(false, 0) } +}; diff --git a/src/progs/base/prog_config.h b/src/progs/base/prog_config.h new file mode 100644 index 0000000..0c772c2 --- /dev/null +++ b/src/progs/base/prog_config.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROGRAMMER_CONFIG_H +#define PROGRAMMER_CONFIG_H + +#include "common/port/port.h" +//#include "generic_prog.h" +#include "prog_group.h" +#include "common/global/generic_config.h" + +namespace Programmer +{ +//---------------------------------------------------------------------------- +class GroupConfig +{ +public: + static PortType portType(const Group &group); + static void writePortType(const Group &group, PortType type); + static QString portDevice(const Group &group, PortType type); + static void writePortDevice(const Group &group, PortType type, const QString &device); + static Port::Description portDescription(const Group &group); + static void writePortDescription(const Group &group, const Port::Description &pd); + static QString firmwareDirectory(const Group &group); + static void writeFirmwareDirectory(const Group &group, const QString &path); +}; + +//---------------------------------------------------------------------------- +BEGIN_DECLARE_CONFIG(Config) + OnlyProgramNonMask = 0, VerifyAfterProgram, OnlyVerifyProgrammed, + PowerDownAfterProgramming, TargetSelfPowered, BlankCheckAfterErase, + PreserveEeprom, ProgramEeprom, RunAfterProgram +END_DECLARE_CONFIG(Config, "programmer") + +} // namespace + +#endif diff --git a/src/progs/base/prog_group.cpp b/src/progs/base/prog_group.cpp new file mode 100644 index 0000000..5801318 --- /dev/null +++ b/src/progs/base/prog_group.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * 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 "prog_group.h" + +#include "common/global/global.h" +#include "generic_prog.h" +#include "prog_config.h" +#include "generic_debug.h" +#include "devices/base/device_group.h" + +// order is important +const PURL::FileType Programmer::INPUT_FILE_TYPE_DATA[Nb_InputFileTypes] = { + PURL::Coff, PURL::Cod, PURL::Hex +}; + +QString Programmer::Group::statusLabel(PortType type) const +{ + uint nb = 0; + FOR_EACH(PortType, ptype) if ( isPortSupported(ptype) ) nb++; + if ( nb<=0 ) return label(); + return label() + " (" + type.label() + ")"; +} + +Programmer::Base *Programmer::Group::createProgrammer(bool targetSelfPowered, const Device::Data *data, const HardwareDescription &hd) const +{ + ::Programmer::Base *base = createBase(data); + Hardware *hardware = createHardware(*base, hd); + DeviceSpecific *ds = (data ? createDeviceSpecific(*base) : 0); + base->init(targetSelfPowered, hardware, ds); + return base; +} + +Debugger::Base *Programmer::Group::createDebugger(::Programmer::Base &base) const +{ + ::Debugger::Base *dbase = createDebuggerBase(base); + if (dbase) { + ::Debugger::DeviceSpecific *dspecific = createDebuggerDeviceSpecific(*dbase); + ::Debugger::Specific *specific = createDebuggerSpecific(*dbase); + dbase->init(dspecific, specific); + } + return dbase; +} + +bool Programmer::Group::checkConnection(const HardwareDescription &hd) const +{ + ::Programmer::Base *base = createProgrammer(false, 0, hd); + bool ok = base->simpleConnectHardware(); + delete base; + return ok; +} + +bool Programmer::Group::isSoftware() const +{ + FOR_EACH(PortType, type) if ( isPortSupported(type) ) return false; + return true; +} diff --git a/src/progs/base/prog_group.h b/src/progs/base/prog_group.h new file mode 100644 index 0000000..07807fe --- /dev/null +++ b/src/progs/base/prog_group.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROG_GROUP_H +#define PROG_GROUP_H + +class QWidget; +#include "common/common/group.h" +#include "common/port/port.h" +#include "common/common/purl_base.h" +#include "generic_prog.h" +namespace Device { class Data; } +namespace Debugger { class Base; class Specific; class DeviceSpecific; } +namespace Hardware { class Config; } + +namespace Programmer +{ +class Base; +class Hardware; +class DeviceSpecific; +class ConfigWidget; + +enum Property { NoProperty = 0, Programmer = 1, Debugger = 2, + CanReleaseReset = 4, HasFirmware = 8, CanUploadFirmware = 16, + NeedDeviceSpecificFirmware = 32, HasSelfTest = 64, + CanReadMemory = 128, HasConnectedState = 256 }; +Q_DECLARE_FLAGS(Properties, Property) +Q_DECLARE_OPERATORS_FOR_FLAGS(Properties) + +enum TargetPowerMode { TargetPowerModeFromConfig, TargetSelfPowered, TargetExternallyPowered }; + +enum { Nb_InputFileTypes = 3 }; +extern const PURL::FileType INPUT_FILE_TYPE_DATA[Nb_InputFileTypes]; + +class Group : public ::Group::Base +{ +public: + virtual QString xmlName() const { return name(); } + virtual ::Hardware::Config *hardwareConfig() const { return 0; } + virtual Properties properties() const = 0; + virtual QString statusLabel(PortType type) const; + virtual bool canReadVoltages() const = 0; + virtual TargetPowerMode targetPowerMode() const = 0; + bool isDebugger() const { return ( properties() & Debugger ); } + bool isSoftware() const; + virtual bool isPortSupported(PortType type) const = 0; + virtual bool checkConnection(const HardwareDescription &hd) const; + ::Programmer::Base *createProgrammer(bool targetSelfPowered, const Device::Data *data, const HardwareDescription &hd) const; + ::Debugger::Base *createDebugger(::Programmer::Base &) const; + virtual uint maxNbBreakpoints(const Device::Data *) const { return 0; } + virtual bool isInputFileTypeSupported(PURL::FileType) const { return false; } + virtual ::Programmer::Base *createBase(const Device::Data *data) const = 0; + +protected: + virtual Hardware *createHardware(::Programmer::Base &base, const HardwareDescription &hd) const = 0; + virtual DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const = 0; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &) const { return 0; } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } + virtual ::Debugger::DeviceSpecific *createDebuggerDeviceSpecific(::Debugger::Base &base) const = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/base/prog_specific.cpp b/src/progs/base/prog_specific.cpp new file mode 100644 index 0000000..a372e92 --- /dev/null +++ b/src/progs/base/prog_specific.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * 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 "prog_specific.h" + +#include "generic_prog.h" + +//----------------------------------------------------------------------------- +Programmer::DeviceSpecific::DeviceSpecific(Programmer::Base &base) + : Log::Base(&base), _base(base) +{} + +//----------------------------------------------------------------------------- +Programmer::Hardware::Hardware(Programmer::Base &base, Port::Base *port, const QString &name) + : Log::Base(&base), _port(port), _name(name), _base(base) +{} + +Programmer::Hardware::~Hardware() +{ + delete _port; +} + +bool Programmer::Hardware::connectHardware() +{ + if (_port) _port->close(); + return internalConnectHardware(); +} + +void Programmer::Hardware::disconnectHardware() +{ + if (_port) _port->close(); + internalDisconnectHardware(); +} + +bool Programmer::Hardware::rawWrite(const QString &data) +{ + Q_ASSERT(_port); + QByteArray a = toAscii(data); + return _port->send(a.data(), a.count()); +} + +bool Programmer::Hardware::rawRead(uint size, QString &data) +{ + Q_ASSERT(_port); + return _port->receive(size, data); +} diff --git a/src/progs/base/prog_specific.h b/src/progs/base/prog_specific.h new file mode 100644 index 0000000..1703bcb --- /dev/null +++ b/src/progs/base/prog_specific.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROG_SPECIFIC_H +#define PROG_SPECIFIC_H + +#include <qfile.h> + +#include "common/global/log.h" +#include "common/port/port_base.h" +#include "common/global/progress_monitor.h" +#include "hardware_config.h" + +namespace Programmer +{ +class Base; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Log::Base +{ +public: + DeviceSpecific(::Programmer::Base &base); + virtual bool setTargetPowerOn(bool on) = 0; + +protected: + ::Programmer::Base &_base; + + virtual bool setPowerOff() = 0; + virtual bool setPowerOn() = 0; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Log::Base +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port, const QString &name); + virtual ~Hardware(); + Port::Description portDescription() const { return _port->description(); } + QString name() const { return _name; } + bool connectHardware(); + bool rawWrite(const QString &data); + bool rawRead(uint size, QString &data); + void disconnectHardware(); + +protected: + Port::Base *_port; + QString _name; + ::Programmer::Base &_base; + + virtual bool internalConnectHardware() = 0; + virtual void internalDisconnectHardware() {} +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/Makefile.am b/src/progs/bootloader/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/bootloader/base/Makefile.am b/src/progs/bootloader/base/Makefile.am new file mode 100644 index 0000000..7c7230d --- /dev/null +++ b/src/progs/bootloader/base/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libbootloader.la +libbootloader_la_SOURCES = bootloader_prog.cpp bootloader.cpp diff --git a/src/progs/bootloader/base/base.pro b/src/progs/bootloader/base/base.pro new file mode 100644 index 0000000..f53b730 --- /dev/null +++ b/src/progs/bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = bootloader +HEADERS += bootloader.h bootloader_prog.h +SOURCES += bootloader.cpp bootloader_prog.cpp diff --git a/src/progs/bootloader/base/bootloader.cpp b/src/progs/bootloader/base/bootloader.cpp new file mode 100644 index 0000000..a45a23f --- /dev/null +++ b/src/progs/bootloader/base/bootloader.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "bootloader.h" diff --git a/src/progs/bootloader/base/bootloader.h b/src/progs/bootloader/base/bootloader.h new file mode 100644 index 0000000..08a0730 --- /dev/null +++ b/src/progs/bootloader/base/bootloader.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 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 BOOTLOADER_H +#define BOOTLOADER_H + +#include "devices/pic/prog/pic_prog.h" + +namespace Bootloader +{ +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : ::Programmer::PicHardware(base, port, QString::null) {} + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data) = 0; + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) = 0; + virtual bool internalConnectHardware() = 0; + virtual bool openPort() { return _port->open(); } +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) { return hardware().read(type, data, vdata); } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool) { return hardware().write(type, data); } +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/base/bootloader_prog.cpp b/src/progs/bootloader/base/bootloader_prog.cpp new file mode 100644 index 0000000..61167f8 --- /dev/null +++ b/src/progs/bootloader/base/bootloader_prog.cpp @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "bootloader_prog.h" + +#include "progs/base/prog_config.h" + +//----------------------------------------------------------------------------- +Bootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : Programmer::PicBase(group, data, name) +{} + +//----------------------------------------------------------------------------- +bool Bootloader::Group::checkConnection(const ::Programmer::HardwareDescription &hd) const +{ + ::Programmer::Base *base = createProgrammer(false, 0, hd); + bool ok = static_cast<Hardware *>(base->hardware())->openPort(); + delete base; + return ok; +} diff --git a/src/progs/bootloader/base/bootloader_prog.h b/src/progs/bootloader/base/bootloader_prog.h new file mode 100644 index 0000000..7b9749e --- /dev/null +++ b/src/progs/bootloader/base/bootloader_prog.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 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 BOOTLOADER_PROG_H +#define BOOTLOADER_PROG_H + +#include "common/global/generic_config.h" +#include "bootloader.h" + +namespace Bootloader +{ +//----------------------------------------------------------------------------- +class ProgrammerBase : public Programmer::PicBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name); + +protected: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual bool checkConnection(const ::Programmer::HardwareDescription &hd) const; +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/bootloader.pro b/src/progs/bootloader/bootloader.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/bootloader/bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/bootloader/gui/Makefile.am b/src/progs/bootloader/gui/Makefile.am new file mode 100644 index 0000000..d52b42b --- /dev/null +++ b/src/progs/bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libbootloaderui.la +libbootloaderui_la_LDFLAGS = $(all_libraries) +libbootloaderui_la_SOURCES = bootloader_ui.cpp diff --git a/src/progs/bootloader/gui/bootloader_ui.cpp b/src/progs/bootloader/gui/bootloader_ui.cpp new file mode 100644 index 0000000..df8595f --- /dev/null +++ b/src/progs/bootloader/gui/bootloader_ui.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "bootloader_ui.h" diff --git a/src/progs/bootloader/gui/bootloader_ui.h b/src/progs/bootloader/gui/bootloader_ui.h new file mode 100644 index 0000000..386c412 --- /dev/null +++ b/src/progs/bootloader/gui/bootloader_ui.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2007 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 BOOTLOADER_UI_H +#define BOOTLOADER_UI_H + +#include <qcheckbox.h> + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/prog_config_widget.h" + +namespace Bootloader +{ + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/direct/Makefile.am b/src/progs/direct/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/direct/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/direct/base/Makefile.am b/src/progs/direct/base/Makefile.am new file mode 100644 index 0000000..99070fe --- /dev/null +++ b/src/progs/direct/base/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libdirectprog.la +libdirectprog_la_SOURCES = direct_pic.cpp direct_baseline.cpp direct_16.cpp \ + direct_16F.cpp direct_18.cpp direct_18F.cpp direct_prog.cpp direct_prog_config.cpp \ + direct_data.cpp direct_mem24.cpp direct.cpp +libdirectprog_la_DEPENDENCIES = direct_data.cpp + +noinst_DATA = direct.xml +direct_data.cpp: ../xml/xml_direct_parser direct.xml + ../xml/xml_direct_parser +CLEANFILES = direct_data.cpp diff --git a/src/progs/direct/base/base.pro b/src/progs/direct/base/base.pro new file mode 100644 index 0000000..97253b4 --- /dev/null +++ b/src/progs/direct/base/base.pro @@ -0,0 +1,10 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = directprog +HEADERS += direct.h direct_data.h direct_pic.h direct_mem24.h direct_prog.h \ + direct_prog_config.h direct_baseline.h direct_16.h direct_16F.h \ + direct_18.h direct_18F.h +SOURCES += direct.cpp direct_data.cpp direct_pic.cpp direct_mem24.cpp direct_prog.cpp \ + direct_prog_config.cpp direct_baseline.cpp direct_16.cpp direct_16F.cpp \ + direct_18.cpp direct_18F.cpp diff --git a/src/progs/direct/base/direct.cpp b/src/progs/direct/base/direct.cpp new file mode 100644 index 0000000..fc53cf3 --- /dev/null +++ b/src/progs/direct/base/direct.cpp @@ -0,0 +1,394 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * Copyright (C) Brian C. Lane * + * * + * 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 "direct.h" + +#include <iostream> + +#include "common/port/parallel.h" +#include "common/port/serial.h" +#include "progs/base/generic_prog.h" +#include "direct_prog_config.h" + +using namespace std; + +//----------------------------------------------------------------------------- +const Direct::PinData Direct::PIN_DATA[Nb_PinTypes] = { + { I18N_NOOP("MCLR (Vpp)"), "0 V", "13 V", "vpp", + I18N_NOOP("The VPP pin is used to select the high voltage programming mode."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Power (Vdd)"), "0 V", "5 V", "vdd", + I18N_NOOP("The VDD pin is used to apply 5V to the programmed device.\nMust be set to GND if your programmer doesn't control the VDD line."), + Port::Out, true, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Clock"), "0 V", "5 V", "clock", + I18N_NOOP("The CLOCK pin is used to synchronize serial data of the DATA IN and DATA OUT pins."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Data Out"), "0 V", "5 V", "datao", + I18N_NOOP("The DATA OUT pin is used to send data to the programmed device."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Data In"), "0 V", "5 V", "datai", + I18N_NOOP("The DATA IN pin is used to receive data from the programmed device."), + Port::In, false, I18N_NOOP("This pin is driven by the programmed device.\nWithout device, it must follow the \"Data out\" pin (when powered on).") }, + { I18N_NOOP("Data R/W"), "Data in", "Data out", "drw", + I18N_NOOP("The DATA RW pin selects the direction of data buffer.\nMust be set to GND if your programmer does not use bi-directionnal buffer."), + Port::Out, true, I18N_NOOP("Check this box to change DATA buffer direction.") } +}; + +//----------------------------------------------------------------------------- +namespace Direct +{ +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &device, Log::Base &base) + : Serial(device, NeedBreak, base) {} + + bool open() { + if ( !Port::Serial::open() ) return false; + if ( !setMode(IgnoreBreak | IgnoreParity, ByteSize8 | EnableReceiver | IgnoreControlLines, S9600, 0) ) return false; + // set up lines for "idle state" ??? + return true; + } +}; +} // namespace + +//----------------------------------------------------------------------------- +Direct::Hardware::Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data) + : ::Programmer::PicHardware(base, port, data.name), _data(data.data) +{} + +bool Direct::Hardware::internalConnectHardware() +{ + if ( !_port->open() ) return false; + + // keep the safe state of rw (read)... + setPin(DataOut, Low); + setPin(Clock, Low); + setPin(Vpp, Off); + setPin(Vdd, Off); + setRead(); + + return true; +} + +void Direct::Hardware::setPin(PinType type, bool on) +{ + int pin = _data.pins[type]; + if ( isGroundPin(pin) ) return; + uint p = (pin<0 ? -pin : pin)-1; + //log(Log::DebugLevel::Extra, QString("Hardware::setPin %1 %2: %3 %4").arg(PIN_DATA[type].label).arg(pin).arg(on).arg(_data.clockDelay)); + _port->setPinOn(p, on, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic)); + if ( type==Clock ) Port::usleep(_data.clockDelay); +} + +bool Direct::Hardware::readBit() +{ + int pin = _data.pins[DataIn]; + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + bool on; + _port->readPin(p, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic), on); + //log(Log::DebugLevel::Extra, QString("Hardware::read DataIn %2: %3").arg(pin).arg(on)); + return on; +} + +uint Direct::Hardware::nbPins(Port::IODir dir) const +{ + return _port->pinData(dir).count(); +} + +QString Direct::Hardware::pinLabelForIndex(Port::IODir dir, uint i) const +{ + Port::PinData pd = _port->pinData(dir)[i]; + return QString("%1 (%2)").arg(pd.pin+1).arg(pd.label); +} + +Port::IODir Direct::Hardware::ioTypeForPin(int pin) const +{ + if ( isGroundPin(pin) ) return Port::NoIO; + uint p = (pin<0 ? -pin : pin)-1; + return _port->ioDir(p); +} + +uint Direct::Hardware::pinForIndex(Port::IODir dir, uint i) const +{ + Q_ASSERT( i<=uint(_port->pinData(dir).count()) ); + if ( i==uint(_port->pinData(dir).count()) ) return _port->groundPin()+1; + return _port->pinData(dir)[i].pin+1; +} + +uint Direct::Hardware::indexForPin(Port::IODir dir, int pin) const +{ + QValueVector<Port::PinData> v = _port->pinData(dir); + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + for (uint i=0; i<uint(v.count()); i++) + if ( v[i].pin==p ) return i; + Q_ASSERT( isGroundPin(pin) ); + return v.count(); +} + +bool Direct::Hardware::isGroundPin(int pin) const +{ + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + return _port->isGroundPin(p); +} + +bool Direct::operator !=(const HData &d1, const HData &d2) +{ + for (uint i=0; i<Nb_PinTypes; i++) + if ( d1.pins[i]!=d2.pins[i] ) return true; + if ( d1.clockDelay!=d2.clockDelay ) return true; + return false; +} + +//----------------------------------------------------------------------------- +Direct::SerialHardware::SerialHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data) + : Hardware(base, new SerialPort(portDevice, base), data) +{} + +Direct::ParallelHardware::ParallelHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data) + : Hardware(base, new Port::Parallel(portDevice, base), data) +{} + +/* +//----------------------------------------------------------------------------- +int Direct::Hardware::hardware_test() +{ + char t[80] ; + + cout << endl << "Please execute this Direct::Hardware test without any PIC" + " connected to your programmer" <<endl << endl ; + + do + { + cout << "Ready for tests ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + if( t[0] == 'n') return -1 ; + + + // stage 1 - hard initialization + // setpins("parallel","/dev/parport0", -5, -4, 3, 2, 10) ; + + //Default RW line not used... + HData data = { { 3, 5, 7, 4, 8, 0 }, 0 }; + Log::ConsoleView view; + Direct::Programmer programmer; + programmer.setView(&view); + SerialHardware hw(programmer, "/dev/ttyS0", data); + if ( !hw.connectHardware() ) { + cout << "Direct::Hardware initialization error" <<endl ; + return 1 ; + } + + + //++Mirko!! + //By Ciri 11/3/2004... + //From here to the end of function i haven't modified nothing... + //--Mirko!! + + // stage 2 - all lines off + hw.setPin(Vpp, Off); + hw.setPin(Vdd, Off); + hw.setPin(Clock, Low); + hw.setPin(DataOut, Low); + cout << "All the following lines must be 0V : " << endl << + "16F84 pin 13 (data out)"<<endl << + "16F84 pin 12 (clock)"<<endl << + "16F84 pin 14 (VDD=power)"<<endl << + "16F84 pin 4 (VPP=prog)"<<endl ; + do + { + cout << "OK ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + + if( t[0] == 'n') return 2 ; + + // stage 3 - data out check + hw.setPin(DataOut, High); + cout << "16F84 pin 13 (data out) must be 5V"<<endl ; + do + { + cout << "OK ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(DataOut, Low); + + if( t[0] == 'n') return 3 ; + + // stage 4 - clock check + hw.setPin(Clock, High); + cout << "16F84 pin 12 (clock) must be 5V"<<endl ; + do + { + cout << "OK ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Clock, Low); + + if( t[0] == 'n') return 4 ; + + // stage 5 - VDD check + hw.setPin(Vdd, On); + cout << "16F84 pin 14 (power) must be 5V"<<endl ; + do + { + cout << "OK ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Vdd, Off) ; + + if( t[0] == 'n') return 5 ; + + // stage 6 - VPP check + hw.setPin(Vpp, On); + cout << "16F84 pin 4 (VDD) must be between 13V and 14V"<<endl ; + do + { + cout << "OK ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Vpp , Off); + + if( t[0] == 'n') return 6 ; + + // stage 7 - test input data + // set data out hi, because bi-directionnal + // on pin 13 uses the open collector capability of 7407 + hw.setPin(DataOut, High); + int in = hw.readBit(); + if( !in ) + { + cout << "DataIn error (16F84 pin 13) : must be 5V and is not" << endl ; + return 7 ; + } + cout << "Please set 16F84 pin 13 (DataIn) low " << + "(connect it to 16F84 pin 5 - GND)" << endl ; + do + { + cout << "Done ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + + in = hw.readBit(); + if(in ) + { + cout << "DataIn error (pin 13) : must be 0V and is not" << endl ; + return 7 ; + } + + cout << "Congratulations! - Direct::Hardware is OK." <<endl ; + return 0 ; +} + +// this is my specific speed test +int Direct::Hardware::timing_test() +{ + char t[80] ; + int cmd ; + long loop = 50000000 ; + + cout << endl << "Please execute this Direct::Hardware test without any PIC" + " connected to your programmer" <<endl << endl ; + + do + { + cout << "Ready for tests ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + if( t[0] == 'n') return -1 ; + + + // stage 1 - hard initialization + //Default Line RW not used... + HData data = { { -5, -4, 3, 2, 10, 25 }, 0 }; + Log::ConsoleView view; + Log::Manager manager; + manager.setView(&view); + ParallelHardware hw("/dev/parport0", manager, data); + if ( !hw.connectHardware() ) { + cout << "Direct::Hardware initialization error" <<endl ; + return 1 ; + } + + //++Mirko!! + //By Ciri 11/3/2004... + //From here to the end of function i have modified nothing... + //--Mirko!! + + // stage 2 - all lines off + hw.setPin(Vpp, Off); + hw.setPin(Vdd, Off); + hw.setPin(Clock, Low); + hw.setPin(DataOut, Low); + + // stage 3 - choose test + cout << "Remember : " << endl << + "16F84 pin 5 is GND"<<endl << + "16F84 pin 13 is data-out"<<endl << + "16F84 pin 12 is clock"<<endl ; + + cout << loop << " periods test .... " << endl ; + + cout << "1 - Maximum speed clock " << endl << + "2 - 100us half period "<<endl << + "3 - load data 0x2AAA (programmer->chip)"<<endl << + "4 - end"<<endl ; + do + { + cout << "CMD (1-4)>> " ; + cin >> cmd ; + } while(cmd < 1 || cmd > 4) ; + + if(cmd == 4) return 2 ; + else if ( cmd == 1) + { + for(long j=0 ; j < loop ; ++j) + { + hw.setPin(Clock, Low); + hw.setPin(Clock, High); + } + } + + else if ( cmd == 2) + { + for(long j=0 ; j < loop ; ++j) + { + hw.setPin(Clock, Low); + Port::usleep(100); + hw.setPin(Clock, High); + Port::usleep(100); + } + } + + else if ( cmd == 3) { + for (long j=0; j<loop; ++j) + { + int d = 0x2AAA ; + d &= 0x3FFF ; // mask unused msb + d <<= 1; // insert start bit + + for (uint x = 0; x<16; x++) { + hw.setPin(Clock, High); + if ( d & 0x01 ) hw.setPin(DataOut, High); + else hw.setPin(DataOut, Low); + hw.setPin(Clock, Low); + d >>= 1; + } + hw.setPin(DataOut, High); + } + } + + return 0; +} +*/ diff --git a/src/progs/direct/base/direct.h b/src/progs/direct/base/direct.h new file mode 100644 index 0000000..6a890b0 --- /dev/null +++ b/src/progs/direct/base/direct.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> * + * Copyright (C) Brian C. Lane * + * * + * 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 DIRECT_H +#define DIRECT_H + +#include "devices/pic/prog/pic_prog.h" + +namespace Direct +{ +enum State { Low = 0, High = 1, Off = Low, On = High }; +enum PinType { Vpp = 0, Vdd, Clock, DataOut, DataIn, DataRW, Nb_PinTypes }; +struct PinData { + const char *label, *offLabel, *onLabel, *key, *comment; + Port::IODir dir; + bool canBeGround; + const char *testComment; +}; +extern const PinData PIN_DATA[Nb_PinTypes]; + +//----------------------------------------------------------------------------- +class HardwareData; +enum Type { Normal, EPEToolkitMK3 }; +struct HData +{ + int pins[Nb_PinTypes]; + uint clockDelay; + Type type; +}; + +class Hardware : public ::Programmer::PicHardware +{ +public: + static Hardware *create(Port::Base *port, const Device::Data &device, const HData &data); + +public: + Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data); + bool readBit(); + void setPin(PinType type, bool on); + void setRead() { setPin(DataRW, true); } + void setWrite() { setPin(DataRW, false); } + + uint nbPins(Port::IODir dir) const; + QString pinLabelForIndex(Port::IODir dir, uint i) const; + Port::IODir ioTypeForPin(int pin) const; + uint pinForIndex(Port::IODir dir, uint i) const; + uint indexForPin(Port::IODir dir, int pin) const; + bool isGroundPin(int pin) const; + Type type() const { return _data.type; } + + // hardware test --- please use it for a newly + // designed/constructed programmer board + // because pin assignation is hard coded in this + // routine, you might have to edit it. ++Gib: + //static int hardware_test(); + // timing test --- please use it to ensure that + // the program meets the timing specifications + //static int timing_test(); + +private: + HData _data; + + virtual bool internalConnectHardware(); + + friend class Programmer; +}; +extern bool operator !=(const HData &d1, const HData &d2); + +class SerialHardware : public Hardware +{ +public: + SerialHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data); +}; + +class ParallelHardware : public Hardware +{ +public: + ParallelHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct.xml b/src/progs/direct/base/direct.xml new file mode 100644 index 0000000..4997450 --- /dev/null +++ b/src/progs/direct/base/direct.xml @@ -0,0 +1,291 @@ +<!-- ************************************************************************* --> +<!-- * 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="direct"> + <device name="10F200" family="10F2XX" support_type="tested" /> + <device name="10F202" family="10F2XX" support_type="tested" /> + <device name="10F204" family="10F2XX" support_type="tested" /> + <device name="10F206" family="10F2XX" support_type="tested" /> + <device name="10F220" family="10F2XX" /> + <device name="10F222" family="10F2XX" /> + <device name="12F508" family="10F2XX" support_type="tested" /> + <device name="12F509" family="10F2XX" support_type="tested" /> + <device name="12F510" family="10F2XX" support_type="tested" /> + + <device name="12C508" family="12C5XX" /> + <device name="12C508A" family="12C5XX" /> + <device name="12C509" family="12C5XX" /> + <device name="12C509A" family="12C5XX" /> + <device name="12CE518" family="12C5XX" /> + <device name="12CE519" family="12C5XX" /> + <device name="12CR509A" family="12C5XX" /> + + <device name="12C671" family="12C67X" /> + <device name="12C672" family="12C67X" /> + <device name="12CE673" family="12C67X" /> + <device name="12CE674" family="12C67X" /> + + <device name="12F629" family="12F675" /> + <device name="12F675" family="12F675" support_type="tested" /> + + <device name="12F635" family="12F6XX_16F6XX" /> + <device name="12F683" family="12F6XX_16F6XX" /> + + <device name="14000" family="12C67X" /> + + <device name="16C432" family="12C67X" /> + <device name="16C433" family="12C67X" /> + + <device name="16C505" family="12C5XX" /> + + <device name="16C554" family="12C67X" /> + <device name="16C557" family="12C67X" /> + <device name="16C558" family="12C67X" /> + + <device name="16C52" family="12C5XX" /> + <device name="16C54" family="12C5XX" /> + <device name="16C54A" family="12C5XX" /> + <device name="16C54B" family="12C5XX" /> + <device name="16C54C" family="12C5XX" /> + <device name="16CR54A" family="12C5XX" /> + <device name="16CR54B" family="12C5XX" /> + <device name="16CR54C" family="12C5XX" /> + <device name="16C55" family="12C5XX" /> + <device name="16C55A" family="12C5XX" /> + <device name="16C56" family="12C5XX" /> + <device name="16C56A" family="12C5XX" /> + <device name="16CR56A" family="12C5XX" /> + <device name="16C57" family="12C5XX" /> + <device name="16C57C" family="12C5XX" /> + <device name="16CR57B" family="12C5XX" /> + <device name="16CR57C" family="12C5XX" /> + <device name="16C58A" family="12C5XX" /> + <device name="16C58B" family="12C5XX" /> + <device name="16CR58A" family="12C5XX" /> + <device name="16CR58B" family="12C5XX" /> + + <device name="16C61" family="12C67X" /> + <device name="16C62" family="12C67X" /> + <device name="16C620" family="12C67X" /> + <device name="16C620A" family="12C67X" /> + <device name="16C621" family="12C67X" /> + <device name="16C621A" family="12C67X" /> + <device name="16C622" family="12C67X" /> + <device name="16C622A" family="12C67X" /> + <device name="16C62A" family="12C67X" /> + <device name="16C62B" family="12C67X" /> + <device name="16C63" family="12C67X" /> + <device name="16C63A" family="12C67X" /> + <device name="16C64" family="12C67X" /> + <device name="16C64A" family="12C67X" /> + <device name="16C65" family="12C67X" /> + <device name="16C65A" family="12C67X" /> + <device name="16C65B" family="12C67X" /> + <device name="16C66" family="12C67X" /> + <device name="16C67" family="12C67X" /> + <device name="16C71" family="12C67X" /> + <device name="16C710" family="12C67X" /> + <device name="16C711" family="12C67X" /> + <device name="16C712" family="12C67X" /> + <device name="16C715" family="12C67X" /> + <device name="16C716" family="12C67X" /> + <device name="16C72" family="12C67X" /> + <device name="16CR72" family="12C67X" /> + <device name="16C72A" family="12C67X" /> + <device name="16C73" family="12C67X" /> + <device name="16C73A" family="12C67X" /> + <device name="16C73B" family="12C67X" /> + <device name="16C74" family="12C67X" /> + <device name="16C745" family="12C67X" /> + <device name="16C74A" family="12C67X" /> + <device name="16C74B" family="12C67X" /> + <device name="16C76" family="12C67X" /> + <device name="16C765" family="12C67X" /> + <device name="16C77" family="12C67X" /> + <device name="16C773" family="12C67X" /> + <device name="16C774" family="12C67X" /> + <device name="16C923" family="12C67X" /> + <device name="16C924" family="12C67X" /> + <device name="16C925" family="12C67X" /> + <device name="16C926" family="12C67X" /> + <device name="16CE623" family="12C67X" /> + <device name="16CE624" family="12C67X" /> + <device name="16CE625" family="12C67X" /> + <device name="16CR62" family="12C67X" /> + <device name="16CR620A" family="12C67X" /> + <device name="16CR63" family="12C67X" /> + <device name="16CR64" family="12C67X" /> + <device name="16CR65" family="12C67X" /> + <device name="16C642" family="12C67X" /> + <device name="16C662" family="12C67X" /> + <device name="16C717" family="12C67X" /> + <device name="16C770" family="12C67X" /> + <device name="16C771" family="12C67X" /> + <device name="16C781" family="12C67X" /> + <device name="16C782" family="12C67X" /> + + <device name="16F54" family="10F2XX" /> + <device name="16F57" family="16F57" /> + <device name="16F59" family="16F57" /> + <device name="16F505" family="10F2XX" /> + <device name="16F506" family="10F2XX" /> + + <device name="16C84" family="16CR8X" /> + <device name="16CR83" family="16CR8X" /> + <device name="16CR84" family="16CR8X" /> + <device name="16F627" family="16F62X" /> + <device name="16F627A" family="16F62XA" /> + <device name="16F628" family="16F62X" /> + <device name="16F628A" family="16F62XA" /> + <device name="16F630" family="12F675" /> + + <device name="16F636" family="12F6XX_16F6XX" /> + <device name="16F639" family="12F6XX_16F6XX" /> + <device name="16F648A" family="16F62XA" /> + <device name="16F676" family="12F675" /> + <device name="16F684" family="12F6XX_16F6XX" /> + <device name="16F685" family="12F6XX_16F6XX" /> + <device name="16F687" family="12F6XX_16F6XX" /> + <device name="16F688" family="12F6XX_16F6XX" /> + <device name="16F689" family="12F6XX_16F6XX" /> + <device name="16F690" family="12F6XX_16F6XX" /> + <device name="16F716" family="12C67X" /> + <device name="16F73" family="16F7X" /> + <device name="16F74" family="16F7X" /> + <device name="16F76" family="16F7X" /> + <device name="16F77" family="16F7X" /> + <device name="16F737" family="16F7X" support_type="tested" /> + <device name="16F747" family="16F7X" support_type="tested" /> + <device name="16F767" family="16F7X" support_type="tested" /> + <device name="16F777" family="16F7X" support_type="tested" /> + <device name="16F785" family="16F913" /> + <device name="16F818" family="16F81X" /> + <device name="16F819" family="16F81X" /> + <device name="16F83" family="16F8X" /> + <device name="16F84" family="16F8X" /> + <device name="16F84A" family="16F84A" /> + <device name="16F87" family="16F81X" /> + <device name="16F870" family="16F87X" /> + <device name="16F871" family="16F87X" support_type="tested" /> + <device name="16F872" family="16F87X" support_type="tested" /> + <device name="16F873" family="16F87X" support_type="tested" /> + <device name="16F873A" family="16F87XA" /> + <device name="16F874" family="16F87X" support_type="tested" /> + <device name="16F874A" family="16F87XA" /> + <device name="16F876" family="16F87X" support_type="tested" /> + <device name="16F876A" family="16F87XA" /> + <device name="16F877" family="16F87X" support_type="tested" /> + <device name="16F877A" family="16F87XA" /> + <device name="16F88" family="16F81X" /> + <device name="16F913" family="16F913" /> + <device name="16F914" family="16F913" /> + <device name="16F916" family="16F916" /> + <device name="16F917" family="16F916" /> + <device name="16F946" family="16F916" /> + + <device name="18F1220" family="18F1220" support_type="tested" /> + <device name="18F1320" family="18F1220" support_type="tested" /> + <device name="18F2220" family="18F1220" support_type="tested" /> + <device name="18F2320" family="18F1220" support_type="tested" /> + <device name="18F4220" family="18F1220" support_type="tested" /> + <device name="18F4320" family="18F1220" support_type="tested" /> + + <device name="18F242" family="18F242" support_type="tested" /> + <device name="18F248" family="18F242" support_type="tested" /> + <device name="18F252" family="18F242" support_type="tested" /> + <device name="18F258" family="18F242" support_type="tested" /> + <device name="18F442" family="18F242" support_type="tested" /> + <device name="18F448" family="18F242" support_type="tested" /> + <device name="18F452" family="18F242" support_type="tested" /> + <device name="18F458" family="18F242" support_type="tested" /> + + <device name="18F1230" family="18F2221" /> + <device name="18F1330" family="18F2221" /> + <device name="18F2221" family="18F2221" /> + <device name="18F2321" family="18F2221" /> + <device name="18F4221" family="18F2221" /> + <device name="18F4321" family="18F2221" /> + <device name="18F2410" family="18F2221" /> + <device name="18F2510" family="18F2221" /> + <device name="18F4410" family="18F2221" /> + <device name="18F4510" family="18F2221" /> + <device name="18F2420" family="18F2221" /> + <device name="18F2520" family="18F2221" /> + <device name="18F4420" family="18F2221" /> + <device name="18F4520" family="18F2221" /> + <device name="18F2480" family="18F2221" /> + <device name="18F2580" family="18F2221" /> + <device name="18F4480" family="18F2221" /> + <device name="18F4580" family="18F2221" /> + <device name="18F2455" family="18F2221" support_type="tested" /> + <device name="18F2450" family="18F2221" /> + <device name="18F2550" family="18F2221" /> + <device name="18F4455" family="18F2221" /> + <device name="18F4450" family="18F2221" /> + <device name="18F4550" family="18F2221" support_type="tested" /> + <device name="18F2515" family="18F2221" /> + <device name="18F2525" family="18F2221" /> + <device name="18F2610" family="18F2221" /> + <device name="18F2620" family="18F2221" /> + <device name="18F4515" family="18F2221" /> + <device name="18F4525" family="18F2221" /> + <device name="18F4610" family="18F2221" /> + <device name="18F4620" family="18F2221" /> + <device name="18F2585" family="18F2221" /> + <device name="18F2680" family="18F2221" /> + <device name="18F4585" family="18F2221" /> + <device name="18F4680" family="18F2221" /> + <device name="18F2682" family="18F2221" /> + <device name="18F4682" family="18F2221" /> + <device name="18F2685" family="18F2221" /> + <device name="18F4685" family="18F2221" /> + + <device name="18F6525" family="18F242" /> + <device name="18F6621" family="18F242" /> + <device name="18F8525" family="18F242" /> + <device name="18F8621" family="18F242" /> + <device name="18F2331" family="18F242" /> + <device name="18F2431" family="18F242" /> + <device name="18F4331" family="18F242" /> + <device name="18F4431" family="18F242" /> + <device name="18F6585" family="18F242" /> + <device name="18F6680" family="18F242" /> + <device name="18F8585" family="18F242" /> + <device name="18F8680" family="18F242" /> + <device name="18F6520" family="18F242" /> + <device name="18F6620" family="18F242" /> + <device name="18F6720" family="18F242" /> + <device name="18F8520" family="18F242" /> + <device name="18F8620" family="18F242" /> + <device name="18F8720" family="18F242" /> + + <device name="18F2439" family="18F2439" /> + <device name="18F4439" family="18F2439" /> + <device name="18F2539" family="18F2539" /> + <device name="18F4539" family="18F2539" /> + + <device name="18F6310" family="18F6310" /> + <device name="18F6410" family="18F6310" /> + <device name="18F8310" family="18F6310" /> + <device name="18F8410" family="18F6310" /> + <device name="18F6390" family="18F6310" /> + <device name="18F6490" family="18F6310" /> + <device name="18F8390" family="18F6310" /> + <device name="18F8490" family="18F6310" /> + + <device name="18F6527" family="18F6527" /> + <device name="18F6622" family="18F6527" /> + <device name="18F6627" family="18F6527" /> + <device name="18F6722" family="18F6527" /> + <device name="18F8527" family="18F6527" /> + <device name="18F8622" family="18F6527" /> + <device name="18F8627" family="18F6527" /> + <device name="18F8722" family="18F6527" /> +</type> diff --git a/src/progs/direct/base/direct_16.cpp b/src/progs/direct/base/direct_16.cpp new file mode 100644 index 0000000..124b35e --- /dev/null +++ b/src/progs/direct/base/direct_16.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 "direct_16.h" + +#include "common/global/global.h" + +//---------------------------------------------------------------------------- +void Direct::pic16::send_bits(BitValue d, uint nbb) +{ + hardware().setWrite(); + for (uint x = nbb; x; --x) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(1+_clockDelay); + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay); + d >>= 1; + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} + +void Direct::pic16::send_word(BitValue d) +{ + hardware().setWrite(); + d <<= 1; // insert start bit + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(1+_clockDelay) ; // needed for slow programmers/fast PCs + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay) ; + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); // Added for ITU-1 support + hardware().setRead(); +} + +// Read 14 bits of data from the PIC +// clock idles low, change data. 1 start bit, 1 stop bit, data valid on falling edge. +BitValue Direct::pic16::get_word() +{ + hardware().setRead(); + BitValue ind = 0; + hardware().setPin(DataOut, High); + for (uint x = 16; x ; --x) { + hardware().setPin(Clock, High); + Port::usleep(1+_clockDelay); + if ( hardware().readBit() ) ind |= 0x8000; + else ind = ind.maskWith(0x7FFF); + ind >>= 1; + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay); + } + return ind; +} + +bool Direct::pic16::incrementPC(uint steps) +{ + for (uint i=0; i<steps; i++) pulseEngine("k6,"); + return true; +} + +BitValue Direct::pic16::readWord(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return pulseEngine("k5,r,"); + return pulseEngine("k4,R,"); +} + +bool Direct::pic16::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + gotoMemory(type); + uint nbWords = data.count(); + bool only = false; + if (vdata) { + bool only = vdata->actions & ::Programmer::OnlyProgrammedVerify; + const Device::Array wdata = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type); + if (only) nbWords = findNonMaskEnd(type, wdata)+1; + } + BitValue mask = device().mask(type); + for (uint i = 0; i<nbWords; i++) { + if ( !only || data[i]!=mask || type!=Pic::MemoryRangeType::Code ) { + data[i] = readWord(type).maskWith(mask); + if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false; + } + incrementPC(1); + } + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(data.count()); + return true; +} + +bool Direct::pic16::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + gotoMemory(type); + for (uint i = 0; i<data.count(); ) { + if ( !writeWords(type, data, i, force) ) { + log(Log::LineType::Error, i18n("Error programming %1 at %2.").arg(type.label()).arg(toHexLabel(i, 8))); + return false; + } + } + return true; +} + +bool Direct::pic16::skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force) +{ + if (force) return false; + uint nb = (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1); + for (uint k=0; k<nb; k++) + if ( data[i+k]!=device().mask(type) ) return false; + incrementPC(nb); + i += nb; + return true; +} + +bool Direct::pic16::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i) +{ + if ( type==Pic::MemoryRangeType::Eeprom) pulseEngine("k3,S,", data[i]); + else { + uint nb = (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1); + for (uint k=0; k<nb; k++) { + if ( k!=0 ) incrementPC(1); + pulseEngine("k2,S,", data[i+k]); + } + } + startProg(type); + QString cmd = QString("w%1").arg(waitProgTime(type)); + pulseEngine(cmd.latin1()); + endProg(type); + return true; +} + +bool Direct::pic16::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force) +{ + if ( skipMaskWords(type, data, i, force) ) return true; + if ( !writeWords(type, data, i) ) return false; + incrementPC(1); + i += (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1); + return true; +} diff --git a/src/progs/direct/base/direct_16.h b/src/progs/direct/base/direct_16.h new file mode 100644 index 0000000..683083e --- /dev/null +++ b/src/progs/direct/base/direct_16.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> * + * 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 DIRECT_16_H +#define DIRECT_16_H + +#include "direct_pic.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class pic16 : public Pic8DeviceSpecific +{ +public: + pic16(::Programmer::Base &base) : Pic8DeviceSpecific(base) {} + virtual BitValue get_word(); + virtual BitValue get_byte() { return get_word().maskWith(0xFF); } + virtual void send_word(BitValue word); + virtual void send_bits(BitValue d, uint nbBits); + virtual void send_cmd(BitValue d) { send_bits(d, 6); } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + +protected: + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + virtual bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force); + virtual bool incrementPC(uint steps); + virtual bool gotoMemory(Pic::MemoryRangeType type) = 0; + virtual uint nbWordsCodeProg() const { return 1; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k8,"); } + virtual uint waitProgTime(Pic::MemoryRangeType type) const = 0; + virtual void endProg(Pic::MemoryRangeType) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force); + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual BitValue readWord(Pic::MemoryRangeType type); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_16F.cpp b/src/progs/direct/base/direct_16F.cpp new file mode 100644 index 0000000..feeb185 --- /dev/null +++ b/src/progs/direct/base/direct_16F.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> * + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2004 Keith Baker <syzygy@pubnix.org> [16F7X] * + * * + * 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 "direct_16F.h" + +#include "common/global/global.h" + +//----------------------------------------------------------------------------- +bool Direct::P16F::gotoTestMemory() +{ + pulseEngine("k0,S,", 0x3FFF); // PC set at 0x2000 + return true; +} + +bool Direct::P16F::gotoMemory(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return true; + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::UserId: return gotoTestMemory(); + case Pic::MemoryRangeType::DeviceId: return (gotoTestMemory() && incrementPC(6)); + case Pic::MemoryRangeType::Config: return (gotoTestMemory() && incrementPC(7)); + case Pic::MemoryRangeType::Cal: + if ( device().range(type).start==device().range(Pic::MemoryRangeType::Code).end+1 ) + return incrementPC(device().range(type).start.toUInt()); + return (gotoTestMemory() && incrementPC(8)); + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F8X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k2,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k3,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F8X::doErase(bool isProtected) +{ + if (isProtected) { // disable code protection + erase code and data + gotoMemory(Pic::MemoryRangeType::Config); + pulseEngine("k1,k7,k8,w10000,k1,k7"); + } else { + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + } + doEmulatedEraseRange(Pic::MemoryRangeType::UserId); + doEmulatedEraseRange(Pic::MemoryRangeType::Config); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F84A::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::UserId ) return 4000 + 4000; // prog +erase + return 4000; +} + +void Direct::P16F84A::startProg(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k24,"); + else pulseEngine("k8,"); +} + +bool Direct::P16F84A::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k2,S,k9,k8,w10000", 0x3FFF); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k3,S,k11,k8,w10000", 0x3FFF); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F84A::doErase(bool isProtected) +{ + if (isProtected) { // disable code protection and erase + gotoMemory(Pic::MemoryRangeType::Config); + pulseEngine("k1,k7,k8,w10000,k1,k7"); + } else { + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + } + doEmulatedEraseRange(Pic::MemoryRangeType::UserId); + doEmulatedEraseRange(Pic::MemoryRangeType::Config); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F7X::waitProgTime(Pic::MemoryRangeType) const +{ + if ( device().name()=="16F72" ) return 3000; + return 1000; +} + +bool Direct::P16F7X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type!=Pic::MemoryRangeType::Code ) return false; + Device::Array array; + if ( !doRead(Pic::MemoryRangeType::Config, array, 0) ) return false; + pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet) + return doWrite(Pic::MemoryRangeType::Config, array, true); +} + +bool Direct::P16F7X::doErase(bool) +{ + pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet) + return doEmulatedEraseRange(Pic::MemoryRangeType::UserId); +} + +//----------------------------------------------------------------------------- +// 16F628 seems to have problems with the standard 16F84 bulk +// erase when disabling code protection : the data memory is not set to 0xFF. +// This code adds a erase/programming pass on the data memory +bool Direct::P16F62X::doErase(bool isProtected) +{ + P16F84A::doErase(isProtected); + if (isProtected) return doEmulatedEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F81X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9w2000"); // bulk erase code: 2ms + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11w2000"); // bulk erase data: 2ms + return true; + } + return false; +} + +bool Direct::P16F81X::doErase(bool) +{ + pulseEngine("k31w8000"); // chip erase: 8ms + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P12F675::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return 6000; + return 2500; +} + +bool Direct::P12F675::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w9000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w9000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P12F675::doErase(bool) +{ + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F62XA::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return 6000; + return 2500; +} + +bool Direct::P16F62XA::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w12000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w12000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F62XA::doErase(bool) +{ + pulseEngine("k0,S,w100", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F87XA::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w8000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w8000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F87XA::doErase(bool) +{ + // I use the command 31 twice because, sometimes, the prog + // memory is not totally erased. Not very elegant, but it works. + pulseEngine("k0,S,k31w8000,k31w8000", 0x3FFF); + return doEmulatedEraseRange(Pic::MemoryRangeType::UserId); +} + +//----------------------------------------------------------------------------- +bool Direct::P16F913::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w6000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w6000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F913::doErase(bool) +{ + // flow chart of figure 3.21 of prog sheet + doEraseRange(Pic::MemoryRangeType::Code); + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F785::doErase(bool) +{ + // flow chart of figure 3.20 of prog sheet + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} diff --git a/src/progs/direct/base/direct_16F.h b/src/progs/direct/base/direct_16F.h new file mode 100644 index 0000000..0b0fca8 --- /dev/null +++ b/src/progs/direct/base/direct_16F.h @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> * + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2004 Keith Baker <syzygy@pubnix.org> [16F7X] * + * * + * 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 DIRECT_16F_HH +#define DIRECT_16F_HH + +#include "direct_16.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class P16F : public pic16 +{ +public: + P16F(::Programmer::Base &base) : pic16(base) {} + bool gotoTestMemory(); + virtual bool gotoMemory(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P16F8X : public P16F +{ +public: + P16F8X(::Programmer::Base &base) : P16F(base) {} + virtual bool doErase(bool isProtected); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 20000; } +}; + +//----------------------------------------------------------------------------- +class P16CR8X : public P16F8X +{ +public: + P16CR8X(::Programmer::Base &base) : P16F8X(base) {} + virtual bool doErase(bool) { return false; } // #### can't the eeprom be bulk erased ??? + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + // #### eeprom and config only can be programmed... +}; + +//----------------------------------------------------------------------------- +class P16F84A : public P16F +{ +public: + P16F84A(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual void startProg(Pic::MemoryRangeType type); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; +}; + +typedef class P16F84A P16F87X; + +//----------------------------------------------------------------------------- +class P16F7X : public P16F +{ +public: + P16F7X(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + uint nbWordsCodeProg() const { return 2; } + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,"); } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F62X : public P16F84A +{ +public: + P16F62X(::Programmer::Base &base) : P16F84A(base) {} + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F81X : public P16F +{ +public: + P16F81X(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + uint nbWordsCodeProg() const { return 4; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k23,"); } +}; + +//----------------------------------------------------------------------------- +class P12F675 : public P16F +{ +public: + P12F675(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F62XA : public P16F +{ +public: + P16F62XA(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F87XA : public P16F +{ +public: + P16F87XA(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint nbWordsCodeProg() const { return 8; } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; } +}; + +//----------------------------------------------------------------------------- +class P16F913 : public P16F +{ +public: + P16F913(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint nbWordsCodeProg() const { return 4; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2500; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k10,w100"); } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +class P16F916 : public P16F913 +{ +public: + P16F916(::Programmer::Base &base) : P16F913(base) {} + virtual uint nbWordsCodeProg() const { return 8; } +}; + +typedef class P16F913 P12F6XX_16F6XX; + +class P16F785 : public P16F913 +{ +public: + P16F785(::Programmer::Base &base) : P16F913(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_18.cpp b/src/progs/direct/base/direct_18.cpp new file mode 100644 index 0000000..d512d32 --- /dev/null +++ b/src/progs/direct/base/direct_18.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 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 "direct_18.h" + +// Commands specific to 18F: +// xhh = send a 8 bits constant (hh must be a 2 digits hex constant) +// Xhhhh = send a 16 bits constant (hhhh must be a 4 digits hex constant) +bool Direct::P18::pulse(const char *&cmd, BitValue value, BitValue &res) +{ + switch (*cmd) { + case 'x': { + uint n; + sscanf(++cmd, "%02X", &n); + ++cmd; + log(Log::DebugLevel::Max, "SEND 1 byte constant : " + toHexLabel(n, 2)); + send_bits(n, 8); + break; + } + case 'X': { + uint n; + sscanf(++cmd,"%04X", &n); + cmd += 3; + log(Log::DebugLevel::Max, "SEND 2 bytes constant : " + toHexLabel(n, 4)); + send_bits(n, 16); + break; + } + default: return Pic8DeviceSpecific::pulse(cmd, value, res); + } + return true; +} + +void Direct::P18::send_word(BitValue d) +{ + hardware().setWrite(); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(_clockDelay+5); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} + +BitValue Direct::P18::get_word() +{ + hardware().setRead(); + BitValue ind = 0; + send_cmd(9); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x-8); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + send_cmd(9); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + return ind; +} + +BitValue Direct::P18::get_byte() +{ + hardware().setRead(); + BitValue ind = 0; + send_cmd(2); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x-8); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + return ind; +} + +void Direct::P18::send_bits(BitValue d, uint nbb) +{ + hardware().setWrite(); + for (int x = nbb; x; --x) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(_clockDelay+5); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} diff --git a/src/progs/direct/base/direct_18.h b/src/progs/direct/base/direct_18.h new file mode 100644 index 0000000..6c2b4f3 --- /dev/null +++ b/src/progs/direct/base/direct_18.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 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 DIRECT_18_HH +#define DIRECT_18_HH + +#include "direct_pic.h" + +namespace Direct +{ + +class P18 : public Pic8DeviceSpecific +{ +public: + P18(::Programmer::Base &base) : Pic8DeviceSpecific(base) {} + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + +protected: + bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual void send_word(BitValue d); + virtual BitValue get_word(); + virtual BitValue get_byte(); + virtual void send_cmd(BitValue d) { send_bits(d, 4); } + virtual void send_bits(BitValue d, uint nbBits); +}; + +} //namespace + +#endif diff --git a/src/progs/direct/base/direct_18F.cpp b/src/progs/direct/base/direct_18F.cpp new file mode 100644 index 0000000..9860e63 --- /dev/null +++ b/src/progs/direct/base/direct_18F.cpp @@ -0,0 +1,318 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 "direct_18F.h" + +#include "direct_data.h" + +//----------------------------------------------------------------------------- +bool Direct::P18F::skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, + uint &i, uint nb, bool forceProgram) +{ + if (forceProgram) return false; + for (uint k=0; k<nb; k++) + if ( data[i+k]!=device().mask(type) ) return false; + i += nb; + return true; +} + +void Direct::P18F::program(Type type) +{ + QString cmd; + switch (type) { + case Code: + cmd = QString("d,C,c,C,c,C,c,Cw%1cw%2X0000,").arg(programHighTime(Code)).arg(programLowTime()); + break; + case Erase: + pulseEngine("k0,X0000,"); // NOP + cmd = QString("k0;w%1;w%2;X0000").arg(programHighTime(type)).arg(programLowTime()); + break; + case Eeprom: + for (;;) { + pulseEngine("k0,X50A6,"); + pulseEngine("k0,X6EF5,"); + pulseEngine("k0,X0000,"); // NOP + BitValue b = get_byte(); + if ( !b.bit(1) ) break; // WR bit clear + } + cmd = QString("w%1").arg(programLowTime()); + break; + } + pulseEngine(cmd); +} + +void Direct::P18F::setCodePointer(uint address) +{ + pulseEngine("k0,S,k0,X6EF8,", 0x0E00 | ((address & 0xFF0000) >> 16)); + pulseEngine("k0,S,k0,X6EF7,", 0x0E00 | ((address & 0x00FF00) >> 8)); + pulseEngine("k0,S,k0,X6EF6,", 0x0E00 | (address & 0x0000FF)); +} + +void Direct::P18F::setPointer(Pic::MemoryRangeType type, uint offset) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k0,S,k0,X6EA9,", 0x0E00 | (offset & 0x00FF)); + pulseEngine("k0,S,k0,X6EAA,", 0x0E00 | ((offset & 0xFF00) >> 8)); + } else setCodePointer(device().range(type).start.toUInt() + offset); +} + +void Direct::P18F::directAccess(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::UserId || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9CA6"); // unset EECON1:CFGS + else pulseEngine("k0,X8CA6"); // set EECON1:CFGS + if ( type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9EA6"); // unset EECON1::EEPGD + else pulseEngine("k0,X8EA6"); // set EECON1::EEPGD +} + +bool Direct::P18F::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + uint offset = 0; + uint nbWords = data.count(); + if (vdata) { + if ( vdata->actions & ::Programmer::OnlyProgrammedVerify ) { + const Device::Array wdata = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type); + offset = findNonMaskStart(type, wdata); + nbWords = findNonMaskEnd(type, wdata)+1; + } + } + BitValue mask = device().mask(type); + //qDebug("read %s %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, device().nbWords(type)); + //pulseEngine("w300000"); // what for ? + directAccess(type); + switch (type.type()) { + case Pic::MemoryRangeType::Eeprom: + for (uint i = 0; i<data.count(); i++) { + setPointer(type, i); + pulseEngine("k0,X80A6,k0,X50A8,k0,X6EF5,k0,X0000"); + data[i] = pulseEngine("r").maskWith(mask); + if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false; + } + _base.progressMonitor().addTaskProgress(data.count()); + break; + case Pic::MemoryRangeType::Code: + setPointer(type, offset); + //pulseEngine("w1000"); ?? + for (uint i=0; i<nbWords; i++) { + data[i] = pulseEngine("R").maskWith(mask); + if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false; + } + _base.progressMonitor().addTaskProgress(data.count()); + break; + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::DeviceId: + setPointer(type, 0); + for (uint i = 0; i<data.count(); i+=2) { + BitValue w = pulseEngine("R"); + data[i] = w.maskWith(mask); + if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false; + data[i+1] = w >> 8; + if ( vdata && !hardware().verifyWord(offset+i+1, data[i+1], type, *vdata) ) return false; + } + break; + default: Q_ASSERT(false); break; + } + return true; +} + +bool Direct::P18F::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + uint inc = device().addressIncrement(type); + //qDebug("write %s %i/%i %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, nbWords, data.count(), inc); + //pulseEngine("w300000"); ?? + configureSinglePanel(); + directAccess(type); + switch (type.type()) { + case Pic::MemoryRangeType::UserId: { + setPointer(type, 0); + Q_ASSERT( device().nbWords(Pic::MemoryRangeType::UserId)==8 ); + uint i = 0; + for (uint k=0; k<4; k++) { + BitValue word = data[i] | data[i+1] << 8; + if ( (k+1)==4 ) pulseEngine("k15,S,", word); + else pulseEngine("k13,S,", word); + i += 2; + } + program(Code); + break; + } + case Pic::MemoryRangeType::Code: { + uint progWidth = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code); + for (uint i = 0; i<data.count(); ) { + if ( i!=0 && i%0x100==0 ) _base.progressMonitor().addTaskProgress(0x100); + if ( skipMaskWords(type, data, i, progWidth, force) ) continue; + setPointer(type, inc * i); + for (uint k=0; k<progWidth; k++) { + if ( (k+1)==progWidth ) pulseEngine("k15,S,", data[i]); + else pulseEngine("k13,S,", data[i]); + i++; + } + program(Code); + } + _base.progressMonitor().addTaskProgress(data.count()%0x100); + break; + } + case Pic::MemoryRangeType::Config: + pulseEngine("k0,XEF00,k0,XF800,"); // move PC somewhere else (0x100000) + for (uint i = 0; i<data.count(); i+=2) { + setPointer(type, inc * i); + BitValue w = data[i] | (data[i+1] << 8); + pulseEngine("k15,S,", w); + program(Code); + pulseEngine("k0,X2AF6,"); // increment address + pulseEngine("k15,S,", w); + program(Code); + pulseEngine("k0,X0000,"); // NOP: some devices need 4 NOPS here... + pulseEngine("k0,X0000,"); // NOP + pulseEngine("k0,X0000,"); // NOP + pulseEngine("k0,X0000,"); // NOP + } + break; + case Pic::MemoryRangeType::Eeprom: + for(uint i = 0; i<data.count(); ) { + if ( i!=0 && i%0x100==0 ) _base.progressMonitor().addTaskProgress(0x100); + if ( skipMaskWords(type, data, i, 1, force) ) continue; + setPointer(type, inc * i); + pulseEngine("k0,S,k0,X6EA8,", data[i] | 0x0E00); // load data + pulseEngine("k0,X84A6,"); // enable memory writes + unlockEeprom(); + pulseEngine("k0,X82A6,"); // write + program(Eeprom); + pulseEngine("k0,X94A6,"); // disable writes + i++; + } + _base.progressMonitor().addTaskProgress(data.count()%0x100); + break; + default: Q_ASSERT(false); break; + } + return true; +} + +void Direct::P18F::unlockEeprom() +{ + pulseEngine("k0,X0E55,k0,X6EA7,k0,X0EAA,k0,X6EA7,"); +} + +bool Direct::P18F::doEraseCommand(uint cmd1, uint cmd2) +{ + if ( cmd1!=0 ) { + setCodePointer(0x3C0005); + pulseEngine("k12;X" + toHex(cmd1, 4)); + } + setCodePointer(0x3C0004); + pulseEngine("k12;X" + toHex(cmd2, 4)); + program(Erase); + return true; +} + +bool Direct::P18F::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + doEraseCommand(0, 0x0083); // boot + for (uint i=0; i<device().config().protection().nbBlocks(); i++) + doEraseCommand(0, 0x0088 + i); + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0, 0x0081); + return false; +} + +bool Direct::P18F::doErase(bool) +{ + return doEraseCommand(0, 0x0080); +} + +//----------------------------------------------------------------------------- +void Direct::P18F1220::program(Type type) +{ + if ( type==Eeprom ) { + pulseEngine("k0,X0000,"); // NOP + QString cmd = QString("k0;w%1;w%2;X0000").arg(programHighTime(type)).arg(programLowTime()); + pulseEngine(cmd); + } else P18F::program(type); +} + +//----------------------------------------------------------------------------- +void Direct::P18F242::configureSinglePanel() +{ + setCodePointer(0x3C0006); + pulseEngine("k12,X0000"); +} + +//----------------------------------------------------------------------------- +bool Direct::P18F2539::doErase(bool) +{ + // apparently there is no chip erase... + return ( doEraseRange(Pic::MemoryRangeType::Code) && doEraseRange(Pic::MemoryRangeType::Eeprom) ); +} + +bool Direct::P18F2539::doEraseCommand(uint cmd1, uint cmd2) +{ + Q_ASSERT( cmd1==0 ); + setCodePointer(0x3C0004); + pulseEngine("k0;X" + toHex(cmd2, 4)); // is that correct ?? + program(Erase); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P18F2439::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + configureSinglePanel(); + directAccess(Pic::MemoryRangeType::Code); + for (uint i=0; i<40; i++) { + setCodePointer(0x200000 + 64*i); + pulseEngine("k0;X84A6;k0;X88A6"); // enable memory writes + setup erase + unlockEeprom(); + pulseEngine("k0;X82A6"); // initiate erase + program(Erase); + pulseEngine("k0;X94A6"); // disable memory writes + } + return true; + } + return P18F2539::doEraseRange(type); +} +//----------------------------------------------------------------------------- +bool Direct::P18F2221::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + doEraseCommand(0, 0x8181); // boot + for (uint i=0; i<device().config().protection().nbBlocks(); i++) { + uint v = (1 << i); + doEraseCommand(v + v<<8, 0x8080); + } + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0, 0x8484); + return false; +} + +bool Direct::P18F2221::doErase(bool) +{ + return doEraseCommand(0x0F0F, 0x8787); // chip erase +} + +//----------------------------------------------------------------------------- +bool Direct::P18F6527::doErase(bool) +{ + return doEraseCommand(0xFFFF, 0x8787); // chip erase +} + +//----------------------------------------------------------------------------- +bool Direct::P18F6310::doErase(bool) +{ + setCodePointer(0x3C0005); + pulseEngine("k12,X010A"); + setCodePointer(0x3C0004); + pulseEngine("k12,X018A"); + program(Erase); + return true; +} diff --git a/src/progs/direct/base/direct_18F.h b/src/progs/direct/base/direct_18F.h new file mode 100644 index 0000000..c3cbcf8 --- /dev/null +++ b/src/progs/direct/base/direct_18F.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 DIRECT_18F_H +#define DIRECT_18F_H + +#include "direct_18.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class P18F : public P18 +{ +public: + P18F(::Programmer::Base &base) : P18(base) {} + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType, const Device::Array &data, bool force); + virtual bool doEraseCommand(uint cmd1, uint cmd2); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + + bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, + uint &i, uint nb, bool force); + void setPointer(Pic::MemoryRangeType type, uint offset); + void setCodePointer(uint address); + enum Type { Code, Eeprom, Erase }; + virtual void program(Type type); + virtual uint programHighTime(Type type) const { return (type==Code ? 1000 : 5000); } + virtual uint programLowTime() { return 5; } + virtual void configureSinglePanel() {} + virtual void unlockEeprom(); + virtual void directAccess(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P18F1220 : public P18F +{ +public: + P18F1220(::Programmer::Base &base) : P18F(base) {} + virtual void program(Type type); +}; + +//----------------------------------------------------------------------------- +class P18F242 : public P18F +{ +public: + P18F242(::Programmer::Base &base) : P18F(base) {} + virtual void configureSinglePanel(); +}; + +//----------------------------------------------------------------------------- +class P18F2539 : public P18F242 +{ +public: + P18F2539(::Programmer::Base &base) : P18F242(base) {} + virtual bool doErase(bool isProtected); + virtual bool doEraseCommand(uint cmd1, uint cmd2); +}; + +//----------------------------------------------------------------------------- +class P18F2439 : public P18F2539 +{ +public: + P18F2439(::Programmer::Base &base) : P18F2539(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P18F2221 : public P18F +{ +public: + P18F2221(::Programmer::Base &base) : P18F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint programLowTime() { return 100; } + virtual void unlockEeprom() {} +}; + +//----------------------------------------------------------------------------- +class P18F6527 : public P18F2221 +{ +public: + P18F6527(::Programmer::Base &base) : P18F2221(base) {} + virtual bool doErase(bool isProtected); +}; + +//----------------------------------------------------------------------------- +class P18F6310 : public P18F +{ +public: + P18F6310(::Programmer::Base &base) : P18F(base) {} + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual uint programHighTime(Type type) const { return (type==Code ? 2000 : 30000); } + virtual uint programLowTime() { return 120; } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool isProtected); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_30.cpp b/src/progs/direct/base/direct_30.cpp new file mode 100644 index 0000000..db3c7f4 --- /dev/null +++ b/src/progs/direct/base/direct_30.cpp @@ -0,0 +1,261 @@ +/*************************************************************************** + * 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 "direct_30.h" + +const uint BULK_ERASE_SEQUENCE[] = { // for all dsPICs + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::LoopStart + 2, + 0x24008A, 0x883B0A, // step 2 + 0x200F80, 0x880190, 0x200067, // step 3 + 0xBB0300, // step 4 + 0xBB1B86, // step 5 + 0x200558, 0x200AA9, 0x883B38, 0x883B39, // step 6 + 0xA8E761, 0x000000, 0x000000, // step 7 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x2407FA, 0x883B0A, // step 9 + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 10 + 0xA8E761, 0x000000, 0x000000, // step 11 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_APPLICATION_ID_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x200800, 0x880190, 0x205FE0, 0x207841, // step 2 + 0xBA0890, 0x000000, 0x000000, + Direct::Pic30::RegisterOut, 0x000000, // step 3 + Direct::Pic30::End +}; +const uint READ_CONFIG_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x200F80, 0x880190, 0xEB0300, 0xEB0380, // step 2 + Direct::Pic30::LoopStart + 7, + 0xBA0BB6, 0x000000, 0x000000, 0x883C20, 0x000000, // step 3 + Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x040100, 0x000000, // step 5 + Direct::Pic30::LoopEnd, + Direct::Pic30::End +}; +const uint WRITE_CONFIG_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::FillAddressLow + 0x200007, // step 2 + 0x24008A, 0x883B0A, // step 3 + 0x200F80, 0x880190, // step 4 + Direct::Pic30::FillData + 0x200000, // step 5 + //0xEB0300, ??? + 0xBB1B96, 0x000000, 0x000000, // step 8 + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_DATA_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200006, // step 2 + 0xEB0380, // step 3 + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + Direct::Pic30::End +}; +const uint WRITE_DATA_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x24005A, 0x883B0A, // step 2 + 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200007, // step 3 + Direct::Pic30::LoopStart + 4, + Direct::Pic30::FillData + 0x200000, // step 4 + Direct::Pic30::FillData + 0x200001, + Direct::Pic30::FillData + 0x200002, + Direct::Pic30::FillData + 0x200003, + 0xEB0300, 0x000000, // step 5 + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_CODE_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::FillAddressHigh + 0x200000, // step 2 + 0x880190, Direct::Pic30::FillAddressLow + 0x200006, + 0xEB0380, // step 3 + 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000, + 0xBADBD6, 0x000000, 0x000000, 0xBA1BB6, 0x000000, 0x000000, + 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000, + 0xBADBD6, 0x000000, 0x000000, 0xBA0BB6, 0x000000, 0x000000, + 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C24, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C25, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + Direct::Pic30::End +}; +const uint WRITE_CODE_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x24001A, 0x883B0A, // step 2 + Direct::Pic30::FillAddressHigh + 0x200000, // step 3 + 0x880190, Direct::Pic30::FillAddressLow + 0x200007, + Direct::Pic30::LoopStart + 8, + Direct::Pic30::FillData + 0x200000, // step 4 + Direct::Pic30::FillData + 0x200001, + Direct::Pic30::FillData + 0x200002, + Direct::Pic30::FillData + 0x200003, + Direct::Pic30::FillData + 0x200004, + Direct::Pic30::FillData + 0x200005, + 0xEB0300, 0x000000, // step 5 + 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000, + 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000, + 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000, + 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, 0x000000, 0x000000, + Direct::Pic30::End +}; + +bool Direct::Pic30::sendCommand(Command cmd) +{ + for (uint i=0; i<4; i++) { + hardware().setPin(DataOut, ((cmd>>i) & 1 ? High : Low)); + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + Port::nsleep(100); + } + return true; +} + +bool Direct::Pic30::executeSIX(uint opcode) +{ + if ( !sendCommand(SIX) ) return false; + for (uint i=0; i<24; i++) { + hardware().setPin(DataOut, ((opcode>>i) & 1 ? High : Low)); + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + // seem to need this longer delay here -- maybe + // specific to my programmer hardware? #### from dspicprg + Port::nsleep(5000); + } + return true; +} + +bool Direct::Pic30::executeREGOUT(uint &v) +{ + v = 0; + if ( !sendCommand(REGOUT) ) return false; + hardware().setPin(DataOut, High); + for (uint i=0; i<24; i++) { + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + // as above, need extra delay here, but even + // longer in this case -- maybe data line takes + // longer to settle when it is being driven by + // the PIC than by the programmer? #### from dspicprg + Port::nsleep(10000); + if ( i>=8 ) { + uint r = hardware().readBit(); + v |= (r << (i-8)); + } + } + return true; +} + +bool Direct::Pic30::doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData) +{ + uint loopStart = 0, loopCound = 0; + for (uint i=0; sequence[i]!=End; i++) { + uint opcode = (sequence[i] & OpcodeMask); + switch (Operation(sequence[i] & OperationMask)) { + case SendSix: + if ( !executeSIX(opcode) ) return false; + break; + case RegisterOut: { + uint v; + if ( !executeREGOUT(v) ) return false; + (*inData) = v & 0xFF; + inData++; + (*inData) = (v >> 8) & 0xFF; + inData++; + break; + } + case Pause: + Port::nsleep(opcode); + break; + case LoopStart: + loopCound = opcode; + loopStart = i; + break; + case LoopEnd: + loopCound--; + if (loopCound) i = loopStart; + break; + case FillData: { + uint v = *outData; + v <<= 4; + outData++; + v |= *outData; + outData++; + v <<= 4; + executeSIX(v | opcode); + break; + } + case FillAddressLow: { + uint v = address & 0xFFFF; + v <<= 4; + executeSIX(v | opcode); + break; + } + case FillAddressHigh: { + uint v = (address & 0xFF0000) >> 16; + v <<= 4; + executeSIX(v | opcode); + break; + } + case End: Q_ASSERT(false); break; + } + } + return true; +} + +bool Direct::Pic30::doErase(bool) +{ + if ( !enterStdpMode() ) return false; + if ( !doStdpSequence(BULK_ERASE_SEQUENCE, 0, 0, 0) ) return false; + return exitStdpMode(); +} + +bool Direct::Pic30::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data) +{ + // #### TODO + return false; +} + +bool Direct::Pic30::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + // #### TODO + return false; +} diff --git a/src/progs/direct/base/direct_30.h b/src/progs/direct/base/direct_30.h new file mode 100644 index 0000000..458496e --- /dev/null +++ b/src/progs/direct/base/direct_30.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * 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 DIRECT_30_H +#define DIRECT_30_H + +#include "direct_pic.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class Pic30 : public PicDeviceSpecific +{ +public: + Pic30(::Programmer::Base &base) : PicDeviceSpecific(base) {} + virtual bool doErase(bool isProtected); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + +public: + enum Operation { SendSix = 0x0000000, RegisterOut = 0x1000000, Pause = 0x2000000, + LoopStart = 0x3000000, LoopEnd = 0x4000000, FillData = 0x5000000, + FillAddressLow = 0x6000000, FillAddressHigh = 0x7000000, End = 0x8000000 }; + enum Mask { OperationMask = 0xF000000, OpcodeMask = 0x0FFFFFF }; + +private: + bool enterStdpMode() { return pulseEngine("cdB"); } + bool exitStdpMode() { return pulseEngine("cdb"); } + bool doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData); + enum Command { SIX = 0x0, REGOUT = 0x1 }; + bool sendCommand(Command command); + bool executeSIX(uint opcode); + bool executeREGOUT(uint &value); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_baseline.cpp b/src/progs/direct/base/direct_baseline.cpp new file mode 100644 index 0000000..996eb12 --- /dev/null +++ b/src/progs/direct/base/direct_baseline.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> * + * 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 "direct_baseline.h" + +//---------------------------------------------------------------------------- +bool Direct::Baseline::gotoMemory(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Config: return true; + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::CalBackup: return incrementPC(device().range(type).start.toUInt()+1); + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +bool Direct::P12C5XX::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i) +{ + BitValue word = data[i]; + // config requires a total of 10ms Pulses == 100 x 100 us + uint total = (type==Pic::MemoryRangeType::Config ? 100 : 8); + uint n = 0; + for (; n<total; n++) { + pulseEngine("k2,S,k8,w100,k14,w5000", word); + if ( readWord(type)==word ) break; + } + if ( n==total ) return false; + if ( type!=Pic::MemoryRangeType::Config ) { + // 11 x (n+1) additionnal passes + for (uint k = 0; k<11*(n+1); k++) + pulseEngine("k2,S,k8,w100,k14,w5000", word); + } + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P10F2XX::doEraseRange(Pic::MemoryRangeType type) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + Device::Array array; + if ( !doRead(Pic::MemoryRangeType::Config, array, 0) ) return false; + gotoMemory(Pic::MemoryRangeType::Config); + pulseEngine("k9,w10000"); // 10ms + return doWrite(Pic::MemoryRangeType::Config, array, true); +} + +bool Direct::P10F2XX::doErase(bool) +{ + gotoMemory(Pic::MemoryRangeType::UserId); + pulseEngine("k9,w10000"); // 10ms + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P12C67X::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i) +{ + BitValue word = data[i]; + // config requires a total of 10ms Pulses == 100 x 100 us + uint total = (type==Pic::MemoryRangeType::Config ? 100 : 25); + uint n = 0; + for (; n<total; n++) { + pulseEngine("k2,S,k8,w100,k14,w5000", word); + if ( readWord(type)==word ) break; + } + if ( n==total ) return false; + if ( type!=Pic::MemoryRangeType::Config ) { + // 3 x (n+1) additionnal passes + for (uint k = 0; k<3*(n+1); k++) + pulseEngine("k2,S,k8,w100,k14,w5000", word); + } + return true; +} diff --git a/src/progs/direct/base/direct_baseline.h b/src/progs/direct/base/direct_baseline.h new file mode 100644 index 0000000..0987dea --- /dev/null +++ b/src/progs/direct/base/direct_baseline.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> * + * 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 DIRECT_BASELINE_HH +#define DIRECT_BASELINE_HH + +#include "direct_16F.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class Baseline : public pic16 +{ +public: + Baseline(::Programmer::Base &base) : pic16(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P12C5XX : public Baseline +{ +public: + P12C5XX(::Programmer::Base &base) : Baseline(base) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return false; } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused +}; + +//----------------------------------------------------------------------------- +class P10F2XX : public Baseline +{ +public: + P10F2XX(::Programmer::Base &base) : Baseline(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,w100"); } +}; + +class P16F57 : public P10F2XX +{ +public: + P16F57(::Programmer::Base &base) : P10F2XX(base) {} + virtual uint nbWordsCodeProg() const { return 4; } +}; + +//----------------------------------------------------------------------------- +class P12C67X : public P16F +{ +public: + P12C67X(::Programmer::Base &base) : P16F(base) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return false; } +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_data.h b/src/progs/direct/base/direct_data.h new file mode 100644 index 0000000..0b84084 --- /dev/null +++ b/src/progs/direct/base/direct_data.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef DIRECT_DATA_H +#define DIRECT_DATA_H + +namespace Direct +{ + +struct Data { +}; +extern const Data &data(const QString &device); + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_mem24.cpp b/src/progs/direct/base/direct_mem24.cpp new file mode 100644 index 0000000..a719add --- /dev/null +++ b/src/progs/direct/base/direct_mem24.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * 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 "direct_mem24.h" + +#include <qdatetime.h> + +#include "common/global/global.h" +#include "common/common/misc.h" + +Direct::Mem24DeviceSpecific::Mem24DeviceSpecific(::Programmer::Base &base) + : ::Programmer::Mem24DeviceSpecific(base) +{} + +bool Direct::Mem24DeviceSpecific::setPowerOn() +{ + hardware().setPin(Clock, Low); + hardware().setPin(DataOut, Low); + hardware().setPin(Vpp, Off); + if ( hardware().isGroundPin(Vdd) ) { + hardware().setPin(Clock, High); + Port::usleep(500000); + } else { + hardware().setPin(Vdd, On); + Port::usleep(10000); + } + return true; +} + +bool Direct::Mem24DeviceSpecific::setPowerOff() +{ + hardware().setPin(Clock, Low); + hardware().setPin(DataOut, Low); + hardware().setPin(Vpp, Off); + hardware().setPin(Vdd, Off); + Port::usleep(10000); + return true; +} + +bool Direct::Mem24DeviceSpecific::verifyPresence() +{ + if ( !start() ) return false; + bool acked; + if ( !writeByte(controlByte(0x0, Write), acked) ) return false; + if ( !acked ) { + log(Log::LineType::Error, i18n("Could not detect EEPROM")); + return false; + } + log(Log::LineType::Information, i18n("EEPROM detected")); + return stop(); +} + +uint Direct::Mem24DeviceSpecific::controlByte(uint address, Operation operation) const +{ + uint cbyte = (operation==Write ? 0xA0 : 0xA1); + uint bsize = device().nbBytes() / device().nbBlocks(); + uint block = address / bsize; + uint nbb = nbBits(device().nbBlocks()-1); + for (uint i=0; i<nbb; i++) + if ( block & (1<<i) ) cbyte |= 1 << (4-nbb+i); + return cbyte; +} + +bool Direct::Mem24DeviceSpecific::setAddress(uint address) +{ + log(Log::DebugLevel::Extra, QString("set address %1").arg(toHexLabel(address, nbChars(NumberBase::Hex, address)))); + if ( !start() ) return false; + uint bsize = device().nbBytes() / device().nbBlocks(); + uint block = address / bsize; + log(Log::DebugLevel::Extra, QString(" in block #%1/%2").arg(block).arg(device().nbBlocks())); + uint cbyte = controlByte(address, Write); + log(Log::DebugLevel::Max, QString(" control byte is %1").arg(toHexLabel(cbyte, 2))); + if ( !writeByteAck(cbyte) ) return false; + uint nb = nbBytes(bsize-1); + for (int i=nb-1; i>=0; i--) { + uint add = (address >> 8*i) & 0xFF; + log(Log::DebugLevel::Max, QString(" byte #%1: %2").arg(i).arg(toHexLabel(add, 2))); + if ( !writeByteAck(add) ) return false; + } + return true; +} + +bool Direct::Mem24DeviceSpecific::doRead(Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + // sequential read: all device memory + if ( !setAddress(0x0) ) return false; + if ( !start() ) return false; + if ( !writeByteAck(controlByte(0x0, Read)) ) return false; + data.resize(device().nbBytes()); + for (uint i=0; i<data.count()-1; i++) data[i] = readByte(Low); + data[data.count()-1] = readByte(High); + if (vdata) { + for (uint i=0; i<data.count(); i++) + if ( !verifyByte(i, data[i], *vdata) ) return false; + } + return stop(); +} + +bool Direct::Mem24DeviceSpecific::doWrite(const Device::Array &data) +{ + QTime time; + // page by page (page_size==1: byte by byte) + uint nbPages = device().nbBytes() / device().nbBytesPage(); + for (uint i=0; i<nbPages; i++) { + log(Log::DebugLevel::Extra, QString("write page #%1/%2").arg(i).arg(nbPages)); + uint address = i * device().nbBytesPage(); + // write bytes + if ( !setAddress(address) ) return false; + for (uint k=0; k<device().nbBytesPage(); k++) + if ( !writeByteAck(data[address+k]) ) return false; + if ( !stop() ) return false; + // poll + time.start(); + for (;;) { + if ( !start() ) return false; + bool acked; + if ( !writeByte(controlByte(address, Write), acked) ) return false; + if (acked) break; + if ( time.elapsed()>200 ) { // 200 ms timeout + log(Log::LineType::Error, i18n("Timeout writing at address %1").arg(toHexLabel(address, nbChars(device().nbBytes())))); + return false; + } + } + } + return true; +} + +void Direct::Mem24DeviceSpecific::set(State clock, State data) +{ + hardware().setPin(Clock, clock); + hardware().setPin(DataOut, data); + Port::usleep(5); // #### needed ? +} + +void Direct::Mem24DeviceSpecific::setData(State data) +{ + set(Low, data); + set(High, data); + set(Low, data); +} + +BitValue Direct::Mem24DeviceSpecific::readByte(State ack) +{ + hardware().setRead(); + set(Low, High); + BitValue b = 0; + for (uint i=0; i<8; i++) { + set(High, High); + b <<= 1; + if ( hardware().readBit() ) b |= 0x1; + set(Low, High); + } + hardware().setWrite(); + setData(ack); + return b; +} + +bool Direct::Mem24DeviceSpecific::writeByteAck(BitValue value) +{ + bool acked; + if ( !writeByte(value, acked) ) return false; + if (!acked) { + log(Log::LineType::Error, i18n("Acknowledge bit incorrect")); + return false; + } + return true; +} + +bool Direct::Mem24DeviceSpecific::writeByte(BitValue value, bool &acked) +{ + Q_ASSERT( value<=0xFF ); + hardware().setWrite(); + set(Low, Low); + for (int i=7; i>=0; i--) setData(value.bit(i) ? High : Low); + hardware().setRead(); + set(Low, High); + set(High, High); + acked = !hardware().readBit(); + hardware().setWrite(); + set(Low, High); + return true; +} + +bool Direct::Mem24DeviceSpecific::start() +{ + hardware().setWrite(); + set(Low, High); + set(High, High); + set(High, Low); + set(Low, Low); + return true; +} + +bool Direct::Mem24DeviceSpecific::stop() +{ + hardware().setWrite(); + set(Low, Low); + set(High, Low); + set(High, High); + set(Low, High); + return true; +} diff --git a/src/progs/direct/base/direct_mem24.h b/src/progs/direct/base/direct_mem24.h new file mode 100644 index 0000000..64f2a9d --- /dev/null +++ b/src/progs/direct/base/direct_mem24.h @@ -0,0 +1,47 @@ +/***************************************************************************\ + * 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 DIRECT_MEM24_H +#define DIRECT_MEM24_H + +#include "devices/mem24/prog/mem24_prog.h" +#include "direct.h" + +namespace Direct +{ + +class Mem24DeviceSpecific : public ::Programmer::Mem24DeviceSpecific +{ +public: + Mem24DeviceSpecific(::Programmer::Base &base); + virtual Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + const Mem24::Data &device() const { return static_cast<const Mem24::Data &>(*::Programmer::DeviceSpecific::_base.device()); } + virtual bool init() { return true; } + virtual bool setPowerOff(); + virtual bool setPowerOn(); + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool verifyPresence(); + +private: + virtual bool doRead(Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(const Device::Array &data); + bool start(); + bool stop(); + BitValue readByte(State ack); + bool writeByte(BitValue value, bool &acked); + bool writeByteAck(BitValue value); + void set(State clock, State data); + void setData(State data); + enum Operation { Write, Read }; + uint controlByte(uint address, Operation operation) const; + bool setAddress(uint address); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_pic.cpp b/src/progs/direct/base/direct_pic.cpp new file mode 100644 index 0000000..30e4722 --- /dev/null +++ b/src/progs/direct/base/direct_pic.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + * 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 "direct_pic.h" + +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +Direct::PulseEngine::PulseEngine(::Programmer::Base &base) + : _pbase(base) +{ + _clockDelay = 0; +} + +BitValue Direct::PulseEngine::pulseEngine(const QString &cmd, BitValue value) +{ + _pbase.log(Log::DebugLevel::Extra, QString("pulse engine: %1").arg(cmd)); + QByteArray a = toAscii(cmd); + BitValue res = 0; + for (const char *ptr=a.data(); (ptr-a.data())<int(a.count()); ++ptr) + if ( !pulse(ptr, value, res) ) qFatal("pulse engine: invalid command '%c'", *ptr); + return res; +} + +// Electric signals level commands: +// UPPER case means signal High - lower case means Low +// Example: "cPCcp" means "clock-low, power on, clock high, clock low, power off". +// c/C = clock +// d/D = data +// p/P = power (vdd) +// Higher level commands: +// wnnnnn = wait nnnnn microseconds (nnnnn is decimal) +// , = a shorthand for w1 +// ; or space = NOP (can be used as separator - useful in debug mode) +bool Direct::PulseEngine::pulse(const char * &cmd, BitValue, BitValue &) +{ + switch (*cmd) { + case ';': + case ' ': + _pbase.log(Log::DebugLevel::Max, "NOP"); + break; + case 'c': + _pbase.log(Log::DebugLevel::Max, "CLOCK L"); + hardware().setPin(Clock, Low); + break; + case 'C': + _pbase.log(Log::DebugLevel::Max, "CLOCK H"); + hardware().setPin(Clock, High); + break; + case 'd': + _pbase.log(Log::DebugLevel::Max, "DATA L"); + hardware().setPin(DataOut, Low); + break; + case 'D': + _pbase.log(Log::DebugLevel::Max, "DATA H"); + hardware().setPin(DataOut, High); + break; + case 'p': + _pbase.log(Log::DebugLevel::Max, "VDD Off"); + hardware().setPin(Vdd, Off); + Port::usleep(10000); + break; + case 'P': + _pbase.log(Log::DebugLevel::Max, "VDD On"); + hardware().setPin(Vdd, On); + // wait 10ms for ALL devices because some programmers (or target board) have capacitors to charge + Port::usleep(10000); + break; + case 'w': { + uint n = 0; + for(; *(cmd+1) && isdigit((int)*(cmd+1)); ++cmd) + n = (n * 10) + *(cmd+1) - '0'; + _pbase.log(Log::DebugLevel::Max, "WAIT " + QString::number(n) + " micro-sec."); + Port::usleep(n); + break; + } + case ',': + _pbase.log(Log::DebugLevel::Max, "WAIT 1 micro-sec"); + Port::usleep(1); + break; + default: return false; + } + return true; +} + +//----------------------------------------------------------------------------- +Direct::PicDeviceSpecific::PicDeviceSpecific(::Programmer::Base &base) + : ::Programmer::PicDeviceSpecific(base), PulseEngine(base) +{} + +// Electric signals level commands: +// UPPER case means signal High - lower case means Low +// b/B = burn (vpp) +bool Direct::PicDeviceSpecific::pulse(const char *&cmd, BitValue value, BitValue &res) +{ + switch (*cmd) { + case 'b': + log(Log::DebugLevel::Max, "VPP Off"); + hardware().setPin(Vpp, Off); + Port::usleep(10); // 10us + break; + case 'B': + log(Log::DebugLevel::Max, "VPP On"); + hardware().setPin(Vpp, On); + Port::usleep(100000); // 100ms + break; + default: return PulseEngine::pulse(cmd, value, res); + } + return true; +} + +bool Direct::PicDeviceSpecific::setPowerOnVddFirst() +{ + setPowerOff(); + switch (hardware().type()) { + case Normal: + if ( hardware().isGroundPin(Vdd) ) { // some programmer cannot change Vdd independently + pulseEngine("B"); // charge capacitor to have high Vdd + pulseEngine("bB"); // turn off Vpp briefly, Vpp on + } else pulseEngine("PB"); + break; + case EPEToolkitMK3: + pulseEngine("B"); // put MCLR at 0V + pulseEngine("bP"); // put MCLR on multiplexer and turn multiplexer to 12V + break; + } + return true; +} + +bool Direct::PicDeviceSpecific::setPowerOnVppFirst() +{ + setPowerOff(); + pulseEngine("BP"); + return true; +} + +bool Direct::PicDeviceSpecific::setPowerOff() +{ + pulseEngine("cdpb"); // turn off Vpp after Vdd to prevent running device + pulseEngine("w50000"); // to be on the safe size with multiple on/off + return true; +} + +bool Direct::PicDeviceSpecific::setTargetPowerOn(bool on) +{ + pulseEngine(on ? "P" : "p"); + return true; +} + +//----------------------------------------------------------------------------- +// Higher level commands: +// S = send data word +// R = read data word +// r = read byte +// knn = send 6 or 4 bits command nn to PIC (nn is decimal) +bool Direct::Pic8DeviceSpecific::pulse(const char *&cmd, BitValue value, BitValue &res) +{ + switch (*cmd) { + case 'S': + log(Log::DebugLevel::Max, "SEND " + toHexLabel(value, 4)); + send_word(value); + break; + case 'R': + log(Log::DebugLevel::Max, "Read Word"); + res = get_word(); + break; + case 'r': + log(Log::DebugLevel::Max, "Read Byte"); + res = get_byte(); + break; + case 'k': { + uint n = 0; + for(; *(cmd+1) && isdigit((int)*(cmd+1)); ++cmd) + n = (n * 10) + *(cmd+1) - '0'; + log(Log::DebugLevel::Max, "SEND cmd " + QString::number(n)); + send_cmd(n); + break; + } + default: return PicDeviceSpecific::pulse(cmd, value, res); + } + return true; +} diff --git a/src/progs/direct/base/direct_pic.h b/src/progs/direct/base/direct_pic.h new file mode 100644 index 0000000..39cd97c --- /dev/null +++ b/src/progs/direct/base/direct_pic.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * 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 DIRECT_PIC_H +#define DIRECT_PIC_H + +#include "devices/pic/pic/pic_memory.h" +#include "direct.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class PulseEngine +{ +public: + PulseEngine(::Programmer::Base &base); + virtual ~PulseEngine() {} + BitValue pulseEngine(const QString &command, BitValue value = 0); + +protected: + ::Programmer::Base &_pbase; + uint _clockDelay; // additionnal delay for buggy hardware + + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual Hardware &hardware() { return static_cast<Hardware &>(*_pbase.hardware()); } +}; + +//----------------------------------------------------------------------------- +class PicDeviceSpecific : public ::Programmer::PicDeviceSpecific, public PulseEngine +{ +public: + PicDeviceSpecific(::Programmer::Base &base); + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + virtual bool setPowerOff(); + virtual bool setTargetPowerOn(bool on); + +protected: + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + bool setPowerOnVddFirst(); + bool setPowerOnVppFirst(); +}; + +//----------------------------------------------------------------------------- +class Pic8DeviceSpecific : public PicDeviceSpecific +{ +public: + Pic8DeviceSpecific(::Programmer::Base &base) : PicDeviceSpecific(base) {} + +protected: + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual void send_word(BitValue word) = 0; + virtual void send_bits(BitValue d, uint nbBits) = 0; + virtual void send_cmd(BitValue d) = 0; + virtual BitValue get_word() = 0; + virtual BitValue get_byte() = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_prog.cpp b/src/progs/direct/base/direct_prog.cpp new file mode 100644 index 0000000..3e4f168 --- /dev/null +++ b/src/progs/direct/base/direct_prog.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * 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 "direct_prog.h" + +#include "devices/base/device_group.h" +#include "devices/list/device_list.h" +#include "direct_prog_config.h" +#include "direct_mem24.h" +//#include "direct_30.h" + +Hardware::Config *Direct::DGroup::hardwareConfig() const +{ + return new Config; +} + +void Direct::DGroup::initSupported() +{ + Group::initSupported(); + // const ::Group::Base *gpic = Device::lister().group("pic"); + ::Group::Base::ConstIterator pit; + // for (pit=gpic->begin(); pit!=gpics->end(); ++pit) { + // ::Group::DeviceData data = pit.data(); + // if ( static_cast<const Pic::Data *>(data.data)->architecture()!=Pic::Architecture::P30X ) continue; + // data.supportType = ::Group::Untested; + // addDevice(data); + // } + const ::Group::Base *gmem24 = Device::lister().group("mem24"); + for (pit=gmem24->begin(); pit!=gmem24->end(); ++pit) addDevice(pit.key(), pit.data().data, pit.data().support); +} + +::Programmer::Base *Direct::DGroup::createBase(const Device::Data *data) const +{ + if ( data==0 || data->group().name()=="pic" ) return new PicBase(*this, static_cast<const Pic::Data *>(data)); + return new Mem24Base(*this, static_cast<const Mem24::Data *>(data)); +} + +::Programmer::Hardware *Direct::DGroup::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + Config config; + HardwareData *hdata = static_cast<HardwareData *>(config.hardwareData(hd.name)); + Q_ASSERT( hdata->portType==hd.port.type ); + ::Programmer::Hardware *hardware = 0; + if ( hd.port.type==PortType::Serial ) hardware = new SerialHardware(base, hd.port.device, *hdata); + else hardware = new ParallelHardware(base, hd.port.device, *hdata); + delete hdata; + return hardware; +} + +::Programmer::DeviceSpecific *Direct::DGroup::createDeviceSpecific(::Programmer::Base &base) const +{ + if ( base.device()->group().name()=="pic" ) { + // if ( static_cast<const Pic::Data *>(base.device())->architecture()==Pic::Architecture::P30X ) return new Pic30(base); + return Group::createDeviceSpecific(base); + } + return new Mem24DeviceSpecific(base); +} diff --git a/src/progs/direct/base/direct_prog.h b/src/progs/direct/base/direct_prog.h new file mode 100644 index 0000000..34ca0b7 --- /dev/null +++ b/src/progs/direct/base/direct_prog.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 DIRECT_PROG_H +#define DIRECT_PROG_H + +#include "common/global/global.h" +#include "progs/base/prog_group.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/mem24/prog/mem24_prog.h" +#include "direct.h" + +namespace Direct +{ + extern bool isSupported(const QString &device); + class Hardware; + +//---------------------------------------------------------------------------- +class PicBase : public ::Programmer::PicBase +{ +Q_OBJECT +public: + PicBase(const ::Programmer::Group &group, const Pic::Data *data) + : ::Programmer::PicBase(group, data, "pic_direct_programmer") {} + +private: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } +}; + +//---------------------------------------------------------------------------- +class Mem24Base : public ::Programmer::Mem24Base +{ +Q_OBJECT +public: + Mem24Base(const ::Programmer::Group &group, const Mem24::Data *data) + : ::Programmer::Mem24Base(group, data, "mem24_direct_programmer") {} + +private: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } +}; + +//---------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup // methods defined in direct_data.cpp +{ +protected: + virtual void initSupported(); + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +class DGroup : public Group +{ +public: + virtual QString name() const { return "direct"; } + virtual QString label() const { return i18n("Direct Programmer"); } + virtual ::Hardware::Config *hardwareConfig() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::Parallel ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const; + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_prog_config.cpp b/src/progs/direct/base/direct_prog_config.cpp new file mode 100644 index 0000000..ffce899 --- /dev/null +++ b/src/progs/direct/base/direct_prog_config.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 "direct_prog_config.h" + +//----------------------------------------------------------------------------- +struct ConstHardwareData +{ + PortType portType; + Direct::HData data; +}; + +struct ConstStandardHardwareData +{ + ::Hardware::DataInfo info; + ConstHardwareData data; +}; + +const ConstStandardHardwareData STANDARD_HARDWARE_DATA[] = { + { { "Tait classic", I18N_NOOP("Tait classic"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Tait 7405/7406", I18N_NOOP("Tait 7405/7406"), 0 }, + { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40 classic", I18N_NOOP("P16PRO40 classic"), 0 }, + { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40 7407", I18N_NOOP("P16PRO40 7407"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40-VPP40 classic", I18N_NOOP("P16PRO40-VPP40 classic"), 0 }, + { PortType::Parallel, { { 6, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40-VPP40 7407", I18N_NOOP("P16PRO40-VPP40 7407"), 0 }, + { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "EPIC+", I18N_NOOP("EPIC+"), + I18N_NOOP("You must disconnect 7407 pin 2") }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "JDM classic", I18N_NOOP("JDM classic"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 0, Direct::Normal } } }, + { { "JDM classic (delay 10)", I18N_NOOP("JDM classic (delay 10)"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 10, Direct::Normal } } }, + { { "JDM classic (delay 20)", I18N_NOOP("JDM classic (delay 20)"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 20, Direct::Normal } } }, + { { "PIC Elmer", I18N_NOOP("PIC Elmer"), 0 }, + { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } }, + { { "Velleman K8048", I18N_NOOP("Velleman K8048"), 0 }, + { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } }, + { { "HOODMICRO", I18N_NOOP("HOODMICRO"), + I18N_NOOP("Webpage: <a href=\"htpp://k9spud.com/hoodmicro\">htpp://k9spud.com/hoodmicro</a>") }, + { PortType::Serial, { { 4, 5, 7, 3, 8, 5 }, 0, Direct::Normal } } }, + + //Added by Mirko Panciri 10/03/2004... + //Visit http://www.pic-tools.com + //I have tested only the "Asix Piccolo" version... + //I think the lines is the same of "Asix Piccolo Grande"... + { { "Asix Piccolo", I18N_NOOP("Asix Piccolo"), 0 }, + { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } }, + { { "Asix Piccolo Grande", I18N_NOOP("Asix Piccolo Grande"), 0 }, + { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } }, + + { { "Propic2 Vpp-1", I18N_NOOP("Propic2 Vpp-1"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Propic2 Vpp-2", I18N_NOOP("Propic2 Vpp-2"), 0 }, + { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Propic2 Vpp-3", I18N_NOOP("Propic2 Vpp-3"), 0 }, + { PortType::Parallel, { { -7, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Myke's EL Cheapo", I18N_NOOP("Myke's EL Cheapo"), 0 }, + { PortType::Parallel, { { 16, 25, -1,-17, 13, 25 }, 0, Direct::Normal } } }, + { { "EL Cheapo classic", I18N_NOOP("EL Cheapo classic"), I18N_NOOP("Not tested.") }, + { PortType::Parallel, { { 16, 25, 1, 17,-13, 25 }, 0, Direct::Normal } } }, + { { "Monty-Robot programmer", I18N_NOOP("Monty-Robot programmer"), 0 }, + { PortType::Parallel, { { -5, 4, 2, 3, 10, 25 }, 0, Direct::Normal } } }, + { { "EPE Toolkit mk3", I18N_NOOP("EPE Toolkit mk3"), + I18N_NOOP("This programmer pulses MCLR from 5V to 0V and then 12V to enter programming mode. It uses a multiplexer to switch between 5V and 12V (Vdd is here the multiplexer pin).<p>Webpage: <a href=\"http://www.epemag.wimborne.co.uk/1001.htm\">http://www.epemag.wimborne.co.uk/1001.htm</a>") }, + { PortType::Parallel, { { 5, 6, 3, 2, 10, 25 }, 0, Direct::EPEToolkitMK3 } } }, + + { { "ETT High Vpp", I18N_NOOP("ETT High Vpp"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "ETT Low Vpp", I18N_NOOP("ETT Low Vpp"), + I18N_NOOP("Compatible with ET-CAB10PIN V2 programmer shipped by Futurlec, with their PIC16F877 controler board.") }, + { PortType::Parallel, { { 3, 5, 2, -1, 10, 25 }, 0, Direct::Normal } } }, + + { { 0, 0, 0 }, + { PortType::Serial, { { 0, 0, 0, 0, 0, 0 }, 0, Direct::Normal } } } +}; + +//----------------------------------------------------------------------------- +void Direct::HardwareData::readConfig(GenericConfig &config) +{ + ::Hardware::Data::readConfig(config); + for (uint i=0; i<Nb_PinTypes; i++) data.pins[i] = config.readIntEntry(PIN_DATA[i].key); + data.clockDelay = config.readIntEntry("clkdelay"); +} + +void Direct::HardwareData::writeConfig(GenericConfig &config) const +{ + ::Hardware::Data::writeConfig(config); + for (uint i=0; i<Nb_PinTypes; i++) config.writeEntry(PIN_DATA[i].key, data.pins[i]); + config.writeEntry("clkdelay", data.clockDelay); +} + +bool Direct::HardwareData::isEqual(const ::Hardware::Data &cdata) const +{ + if ( !::Hardware::Data::isEqual(cdata) ) return false; + const HData &hdata = static_cast<const HardwareData &>(cdata).data; + if ( data.clockDelay!=hdata.clockDelay ) return false; + for (uint i=0; i<Nb_PinTypes; i++) + if ( data.pins[i]!=hdata.pins[i] ) return false; + return true; +} + +//----------------------------------------------------------------------------- +QStringList Direct::Config::standardHardwareNames(PortType type) const +{ + QStringList names; + for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++) + if ( STANDARD_HARDWARE_DATA[i].data.portType==type ) names += STANDARD_HARDWARE_DATA[i].info.name; + return names; +} + +const Hardware::DataInfo *Direct::Config::standardHardwareDataInfo(const QString &name) const +{ + for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++) { + const ConstStandardHardwareData &csdata = STANDARD_HARDWARE_DATA[i]; + if ( csdata.info.name==name) return &csdata.info; + } + return 0; +} + +Hardware::Data *Direct::Config::standardHardwareData(const QString &name) const +{ + for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++) { + const ConstStandardHardwareData &csdata = STANDARD_HARDWARE_DATA[i]; + if ( csdata.info.name!=name) continue; + HardwareData *data = new HardwareData; + data->name = csdata.info.name; + data->portType = csdata.data.portType; + data->data = csdata.data.data; + return data; + } + return 0; +} diff --git a/src/progs/direct/base/direct_prog_config.h b/src/progs/direct/base/direct_prog_config.h new file mode 100644 index 0000000..151b141 --- /dev/null +++ b/src/progs/direct/base/direct_prog_config.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2005 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 DIRECT_PROG_CONFIG_H +#define DIRECT_PROG_CONFIG_H + +#include "direct.h" +#include "progs/base/hardware_config.h" + +namespace Direct +{ + +class HardwareData : public ::Hardware::Data +{ +public: + virtual void readConfig(GenericConfig &config); + virtual void writeConfig(GenericConfig &config) const; + virtual bool isEqual(const ::Hardware::Data &data) const; + HData data; +}; + +class Config : public ::Hardware::Config +{ +public: + Config() : ::Hardware::Config("direct_programmer") {} + +protected: + virtual QStringList standardHardwareNames(PortType type) const; + virtual const ::Hardware::DataInfo *standardHardwareDataInfo(const QString &name) const; + virtual ::Hardware::Data *standardHardwareData(const QString &name) const; + virtual ::Hardware::Data *createHardwareData() const { return new HardwareData; } +}; + +} //namespace + +#endif diff --git a/src/progs/direct/direct.pro b/src/progs/direct/direct.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/direct/direct.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/direct/gui/Makefile.am b/src/progs/direct/gui/Makefile.am new file mode 100644 index 0000000..ec7e698 --- /dev/null +++ b/src/progs/direct/gui/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libdirectui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libdirectui.la +libdirectui_la_SOURCES = direct_config_widget.cpp diff --git a/src/progs/direct/gui/direct_config_widget.cpp b/src/progs/direct/gui/direct_config_widget.cpp new file mode 100644 index 0000000..985cacd --- /dev/null +++ b/src/progs/direct/gui/direct_config_widget.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** + * 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 "direct_config_widget.h" + +#include <qtooltip.h> +#include <qcheckbox.h> +#include <qtimer.h> +#include <qpushbutton.h> + +#include "progs/direct/base/direct_prog_config.h" +#include "progs/direct/base/direct_prog.h" + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *Direct::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} + +//----------------------------------------------------------------------------- +const char * const INV_PIN_LABEL = I18N_NOOP("Check this option if your hardware uses negative logic for this pin."); +const char * const DELAY_LABEL = I18N_NOOP("Some programming cards need low clock rate:\nadding delay to clock pulses might help."); + +Direct::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit) + : ::Hardware::HConfigWidget(base, parent, edit) +{ + // pins assignment + QGroupBox *groupb = new QGroupBox(1, Horizontal, i18n("Pin assignment"), this); + _mainVBox->addWidget(groupb); + QWidget *w = new QWidget(groupb); + QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10); + if (edit) grid->setColStretch(5, 1); + for (uint i=0; i<Nb_PinTypes; i++) { + QLabel *label = new QLabel(i18n(PIN_DATA[i].label), w); + QToolTip::add(label, PIN_DATA[i].comment); + grid->addWidget(label, i, 0); + _combos[i] = new QComboBox(w); + _combos[i]->setEnabled(edit); + connect(_combos[i], SIGNAL(activated(int)), SLOT(slotPinChanged())); + QToolTip::add(_combos[i], PIN_DATA[i].comment); + grid->addWidget(_combos[i], i, 1); + _invcbs[i] = new QCheckBox(i18n("Inverted"), w); + _invcbs[i]->setEnabled(edit); + QToolTip::add(_invcbs[i], i18n(INV_PIN_LABEL)); + grid->addWidget(_invcbs[i], i, 2); + if (edit) { + _testcbs[i] = new QCheckBox(i18n("on"), w); + QToolTip::add(_testcbs[i], PIN_DATA[i].testComment); + connect(_testcbs[i], SIGNAL(clicked()), SLOT(slotTestPin())); + grid->addWidget(_testcbs[i], i, 3); + _testLabels[i] = new QLabel(w); + QToolTip::add(_testcbs[i], PIN_DATA[i].testComment); + grid->addWidget(_testLabels[i], i, 4); + updateTestStatus(PinType(i), false); + } else { + _testcbs[i] = 0; + _testLabels[i] = 0; + } + } + + QHBoxLayout *hbox = new QHBoxLayout(_mainVBox); + QLabel *label = new QLabel(i18n("Clock delay"), this); + QToolTip::add(label, i18n(DELAY_LABEL)); + hbox->addWidget(label); + _delay = new KIntNumInput(0, Horizontal, this); + _delay->setRange(0, 50, 5); + _delay->setEnabled(edit); + QToolTip::add(_delay, i18n(DELAY_LABEL)); + hbox->addWidget(_delay); + + if (edit) { + _sendBitsButton = new QPushButton(i18n("Send 0xA55A"), this); + _sendBitsButton->setToggleButton(true); + connect(_sendBitsButton, SIGNAL(clicked()), SLOT(sendBits())); + QToolTip::add(_sendBitsButton, i18n("Continuously send 0xA55A on \"Data out\" pin.")); + _editVBox->addWidget(_sendBitsButton); + _editVBox->addStretch(1); + } else _sendBitsButton = 0; + + // timer for sending bits + _timerSendBits = new QTimer(this); + connect(_timerSendBits, SIGNAL(timeout()), SLOT(slotSendBits())); + + // timer for automatically polling DataOut pin + _timerPollDataOut = new QTimer(this); + connect(_timerPollDataOut, SIGNAL(timeout()), SLOT(updateDataIn())); +} + +void Direct::HConfigWidget::sendBits() +{ + if ( _timerSendBits->isActive() ) { + _sendBitsButton->setText(i18n("Send 0xA55A")); + _timerSendBits->stop(); + updateTestPin(DataOut); + } else { + _sendBitsButton->setText(i18n("Stop")); + _timerSendBits->start(1); + } +} + +uint Direct::HConfigWidget::pin(PinType ptype) const +{ + return static_cast<const Hardware *>(_hardware)->pinForIndex(PIN_DATA[ptype].dir, _combos[ptype]->currentItem()); +} + +void Direct::HConfigWidget::slotPinChanged() +{ + for (uint i = 0; i<Nb_PinTypes; i++) { + if ( sender()!=_combos[i] ) continue; + updatePin(PinType(i)); + } +} + +void Direct::HConfigWidget::updatePin(PinType ptype) +{ + bool ground = hardware()->isGroundPin(pin(ptype)); + _invcbs[ptype]->setEnabled(_edit); + if (ground) _invcbs[ptype]->hide(); + else _invcbs[ptype]->show(); + if (_edit) { + _testcbs[ptype]->setEnabled(PIN_DATA[ptype].dir==Port::Out && _connected); + _testLabels[ptype]->setEnabled(_connected); + if (ground) { + _testcbs[ptype]->hide(); + _testLabels[ptype]->hide(); + } else { + _testcbs[ptype]->show(); + _testLabels[ptype]->show(); + } + } +} + +void Direct::HConfigWidget::slotTestPin() +{ + for (uint i = 0; i<Nb_PinTypes; i++) { + if ( sender()!=_testcbs[i] ) continue; + updateTestPin(PinType(i)); + break; + } +} + +void Direct::HConfigWidget::updateTestPin(PinType ptype) +{ + Q_ASSERT( _connected && ptype!=DataIn ); + bool on = _testcbs[ptype]->isChecked(); + hardware()->setPin(ptype, on); + updateTestStatus(ptype, on); + if ( ptype==Vpp ) updateDataIn(); +} + +void Direct::HConfigWidget::updateTestStatus(PinType ptype, bool on) +{ + if (on) _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].onLabel)); + else _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].offLabel)); +} + +void Direct::HConfigWidget::updateDataIn() +{ + bool on = hardware()->readBit(); + updateTestStatus(DataIn, on); + _testcbs[DataIn]->setChecked(on); +} + +void Direct::HConfigWidget::sendBits(uint d, int nbb) +{ + Q_ASSERT(_connected); + hardware()->setWrite(); + for (; nbb; --nbb) { + hardware()->setPin(Clock, High); + if ( d & 0x01 ) hardware()->setPin(DataOut, High); + else hardware()->setPin(DataOut, Low); + hardware()->setPin(Clock, Low); + d >>= 1; // Move the data over 1 bit + } + hardware()->setPin(DataOut, Low); + hardware()->setRead(); +} + +void Direct::HConfigWidget::slotSendBits() +{ + sendBits(0xA55A, 16); +} + +bool Direct::HConfigWidget::set(const Port::Description &pd, const ::Hardware::Data &data) +{ + // connect port + _timerPollDataOut->stop(); + if ( _timerSendBits->isActive() ) sendBits(); // stop + delete _hardware; + const HardwareData &hdata = static_cast<const HardwareData &>(data); + if ( pd.type==PortType::Serial ) _hardware = new SerialHardware(_base, pd.device, hdata); + else _hardware = new ParallelHardware(_base, pd.device, hdata); + bool ok = _hardware->connectHardware(); + if ( !_edit) _hardware->disconnectHardware(); + else _connected = ok; + + // update GUI + if (_edit) { + for (uint i=0; i<Nb_PinTypes; i++) { + _testcbs[i]->setEnabled(_connected); + updateTestStatus(PinType(i), false); + } + if ( _connected ) _timerPollDataOut->start(100); + _sendBitsButton->setEnabled(_connected); + } + + // update pins + for (uint i=0; i<Nb_PinTypes; i++) { + _combos[i]->clear(); + Port::IODir dir = PIN_DATA[i].dir; + for (uint k=0; k<hardware()->nbPins(dir); k++) + _combos[i]->insertItem(hardware()->pinLabelForIndex(dir, k)); + if (PIN_DATA[i].canBeGround) _combos[i]->insertItem("GND"); + _combos[i]->setCurrentItem(hardware()->indexForPin(dir, hdata.data.pins[i])); + _invcbs[i]->setChecked(hdata.data.pins[i]<0); + updatePin(PinType(i)); + } + _delay->setValue(hdata.data.clockDelay); + + return ok; +} + +Hardware::Data *Direct::HConfigWidget::data() const +{ + HardwareData *hdata = new HardwareData; + hdata->portType = _hardware->portDescription().type; + for (uint i=0; i<Nb_PinTypes; i++) { + hdata->data.pins[i] = pin(PinType(i)); + if ( _invcbs[i]->isChecked() ) hdata->data.pins[i] = -hdata->data.pins[i]; + } + hdata->data.clockDelay = _delay->value(); + return hdata; +} + +//----------------------------------------------------------------------------- +Direct::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Hardware::ConfigWidget(new ::Direct::PicBase(group, 0), new Config, parent) +{} + +Hardware::HConfigWidget *Direct::ConfigWidget::createHardwareConfigWidget(QWidget *parent, bool edit) const +{ + return new HConfigWidget(*_base, parent, edit); +} diff --git a/src/progs/direct/gui/direct_config_widget.h b/src/progs/direct/gui/direct_config_widget.h new file mode 100644 index 0000000..4a5e4c6 --- /dev/null +++ b/src/progs/direct/gui/direct_config_widget.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 DIRECT_CONFIG_WIDGET +#define DIRECT_CONFIG_WIDGET + +#include <knuminput.h> + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/hardware_config_widget.h" +#include "progs/direct/base/direct.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +//----------------------------------------------------------------------------- +class HConfigWidget : public ::Hardware::HConfigWidget +{ +Q_OBJECT +public: + HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit); + virtual bool set(const Port::Description &pd, const ::Hardware::Data &data); + virtual ::Hardware::Data *data() const; + +private slots: + void slotTestPin(); + void slotPinChanged(); + void updateDataIn(); + void sendBits(); + void slotSendBits(); + +private: + QComboBox *_combos[Nb_PinTypes]; + QCheckBox *_invcbs[Nb_PinTypes]; + QCheckBox *_testcbs[Nb_PinTypes]; + QLabel *_testLabels[Nb_PinTypes]; + KIntNumInput *_delay; + QPushButton *_sendBitsButton; + QTimer *_timerSendBits, *_timerPollDataOut; + + void sendBits(uint d, int nbb); + void updateTestPin(PinType ptype); + void updateTestStatus(PinType ptype, bool on); + uint pin(PinType ptype) const; + void updatePin(PinType ptype); + Hardware *hardware() { return static_cast<Hardware *>(_hardware); } +}; + +//----------------------------------------------------------------------------- +class ConfigWidget : public ::Hardware::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual ::Hardware::HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/xml/Makefile.am b/src/progs/direct/xml/Makefile.am new file mode 100644 index 0000000..dd1f678 --- /dev/null +++ b/src/progs/direct/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_direct_parser +xml_direct_parser_SOURCES = xml_direct_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_direct_parser_DEPENDENCIES = $(OBJECTS) +xml_direct_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/direct/xml/xml.pro b/src/progs/direct/xml/xml.pro new file mode 100644 index 0000000..740232e --- /dev/null +++ b/src/progs/direct/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_direct_parser +SOURCES += xml_direct_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_direct_parser +unix:QMAKE_CLEAN += ../base/direct_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_direct_parser.exe +win32:QMAKE_CLEAN += ..\base\direct_data.cpp diff --git a/src/progs/direct/xml/xml_direct_parser.cpp b/src/progs/direct/xml/xml_direct_parser.cpp new file mode 100644 index 0000000..ee51674 --- /dev/null +++ b/src/progs/direct/xml/xml_direct_parser.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "devices/pic/base/pic.h" +#include "progs/direct/base/direct_data.h" + +namespace Direct +{ +class XmlToData : public ::Programmer::XmlToData<Data> +{ +public: + XmlToData() : ::Programmer::XmlToData<Data>("direct", "Direct") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void includes(QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Direct::XmlToData::parseData(QDomElement element, Data &) +{ + QString s = element.attribute("pwidth"); + const Device::Data *d = Device::lister().data(currentDevice()); + if ( d==0 ) qFatal("Invalid device name"); +} + +void Direct::XmlToData::includes(QTextStream &s) const +{ + Programmer::XmlToData<Data>::includes(s); + s << "#include \"direct_baseline.h\"" << endl; + s << "#include \"direct_16F.h\"" << endl; + s << "#include \"direct_18F.h\"" << endl; +} + +void Direct::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData<Data>::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Direct::Group::createDeviceSpecific(::Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast<PicBase &>(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i<uint(families().count()); i++) { + s << " case " + QString::number(i) + ": return new P" + families()[i] + "(base);" << endl; + } + s << " }" << endl; + s << " Q_ASSERT(false);" << endl; + s << " return 0;" << endl; + s << "}" << endl; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Direct::XmlToData) diff --git a/src/progs/gpsim/Makefile.am b/src/progs/gpsim/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/gpsim/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/gpsim/base/Makefile.am b/src/progs/gpsim/base/Makefile.am new file mode 100644 index 0000000..b008527 --- /dev/null +++ b/src/progs/gpsim/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +libgpsim_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libgpsim.la +libgpsim_la_SOURCES = gpsim.cpp gpsim_debug.cpp diff --git a/src/progs/gpsim/base/base.pro b/src/progs/gpsim/base/base.pro new file mode 100644 index 0000000..4b05ac5 --- /dev/null +++ b/src/progs/gpsim/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = gpsim +HEADERS += gpsim.h gpsim_debug.h +SOURCES += gpsim.cpp gpsim_debug.cpp diff --git a/src/progs/gpsim/base/gpsim.cpp b/src/progs/gpsim/base/gpsim.cpp new file mode 100644 index 0000000..e6c17bd --- /dev/null +++ b/src/progs/gpsim/base/gpsim.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** + * 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 "gpsim.h" + +#include <qregexp.h> +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" + +//----------------------------------------------------------------------------- +GPSim::Process::Process(Log::Base *base) + : ::Process::LineOutput(0, "gpsim_process"), Log::Base(base), _ready(false) +{ + connect(this, SIGNAL(stdoutDataReceived()), SLOT(stdoutDataReceivedSlot())); +} + +void GPSim::Process::stdoutDataReceivedSlot() +{ + if ( _stdout.startsWith("**gpsim> ") || _ready ) { + log(Log::DebugLevel::Extra, "received console prompt", Log::Delayed); + _ready = true; + emit requestSynchronousStop(); + } +} + +void GPSim::Process::addStdoutLine(const QString &line) +{ + log(Log::DebugLevel::Extra, " " + line, Log::Delayed); + if ( line.startsWith("***ERROR:") ) { + log(Log::LineType::Error, line); + return; + } + QString s = line; + QString prompt = "**gpsim> "; + while ( s.startsWith(prompt) ) { + _ready = true; + s = s.mid(prompt.length()); + } + s = s.stripWhiteSpace(); + _stdoutLines += s; +} + +//----------------------------------------------------------------------------- +GPSim::ProcessManager::ProcessManager(Log::Base *base) + : Log::Base(base), _process(base) +{} + +bool GPSim::ProcessManager::start() +{ + _process._ready = false; + _process.setup("gpsim", QStringList("-i"), false); + if ( !_process.start(0) ) { + log(Log::LineType::Error, i18n("Failed to start \"gpsim\".")); + return false; + } + return runSynchronously(); +} + +bool GPSim::ProcessManager::runSynchronously() +{ + ::Process::State state = ::Process::runSynchronously(_process, ::Process::NoRunAction, 5000); + if ( !_process.isRunning() ) { + log(Log::LineType::Error, i18n("\"gpsim\" unexpectedly exited.")); + return false; + } + if ( state==::Process::Timedout ) { + log(Log::LineType::Error, i18n("Timeout waiting for \"gpsim\".")); + return false; + } + return true; +} + +bool GPSim::ProcessManager::sendCommand(const QString &cmd, bool synchronous) +{ + _process._ready = false; + _process._stdoutLines.clear(); + _process._stdout = QString::null; + _process.writeToStdin(cmd + '\n'); + if (synchronous) return runSynchronously(); + return true; +} + +bool GPSim::ProcessManager::sendSignal(uint n, bool synchronous) +{ + _process._ready = false; + _process._stdoutLines.clear(); + _process._stdout = QString::null; + if ( !_process.signal(n) ) { + log(Log::LineType::Error, i18n("Error send a signal to the subprocess.")); + return false; + } + if (synchronous) return runSynchronously(); + return true; +} + +bool GPSim::ProcessManager::getVersion(VersionData &version) +{ + if ( !sendCommand("version", true) ) return false; + QRegExp reg("\\w*\\s*(\\d+\\.\\d+\\.\\d+).*"); + if ( _process.sout().count()==0 || !reg.exactMatch(_process.sout()[0]) ) { + version = VersionData(); + return true; + } + version = VersionData::fromString(reg.cap(1)); + return true; +} + +//----------------------------------------------------------------------------- +GPSim::Hardware::~Hardware() +{ + delete _manager; +} + +bool GPSim::Hardware::internalConnectHardware() +{ + delete _manager; + _manager = new ProcessManager(this); + _manager->process().setWorkingDirectory(_base.debugger()->directory()); + if ( !_manager->start() ) return false; + if ( !_manager->getVersion(_version) ) return false; + if ( !_version.isValid() ) { + log(Log::LineType::Error, i18n("Could not recognize gpsim version.")); + return false; + } + return true; +} + +void GPSim::Hardware::internalDisconnectHardware() +{ + delete _manager; + _manager = 0; +} + +bool GPSim::Hardware::execute(const QString &command, bool synchronous, QStringList *output) +{ + log(Log::DebugLevel::Normal, QString("command: %1").arg(command)); + if (output) output->clear(); + if ( !_manager->sendCommand(command, synchronous) ) return false; + if (output) *output = _manager->process().sout(); + return true; +} + +bool GPSim::Hardware::signal(uint n, bool synchronous, QStringList *output) +{ + log(Log::DebugLevel::Normal, QString("signal: %1").arg(n)); + if (output) output->clear(); + if ( !_manager->sendSignal(n, synchronous) ) return false; + if (output) *output = _manager->process().sout(); + return true; +} diff --git a/src/progs/gpsim/base/gpsim.h b/src/progs/gpsim/base/gpsim.h new file mode 100644 index 0000000..ab004a3 --- /dev/null +++ b/src/progs/gpsim/base/gpsim.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * 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 GPSIM_H +#define GPSIM_H + +#include "common/common/version_data.h" +#include "progs/base/prog_specific.h" +#include "common/global/process.h" +#include "common/global/purl.h" + +namespace GPSim +{ +//----------------------------------------------------------------------------- +class Process : public ::Process::LineOutput, public Log::Base +{ +Q_OBJECT +public: + Process(Log::Base *base); + +private slots: + void stdoutDataReceivedSlot(); + +private: + bool _ready; + + virtual void addStdoutLine(const QString &line); + + friend class ProcessManager; +}; + +//----------------------------------------------------------------------------- +class ProcessManager : public Log::Base +{ +public: + ProcessManager(Log::Base *base); + Process &process() { return _process; } + bool isReady() const { return _process._ready; } + bool start(); + bool runSynchronously(); + bool sendCommand(const QString &cmd, bool synchronous); + bool sendSignal(uint n, bool synchronous); + bool getVersion(VersionData &version); + +private: + Process _process; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Programmer::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Programmer::Hardware(base, 0, QString::null), _manager(0) {} + virtual ~Hardware(); + bool isReady() const { return _manager->isReady(); } + bool execute(const QString &command, bool synchronous, QStringList *output = 0); + bool signal(uint n, bool synchronous, QStringList *output = 0); + const VersionData &version() const { return _version; } + +private: + ProcessManager *_manager; + VersionData _version; + + virtual bool internalConnectHardware(); + virtual void internalDisconnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::DeviceSpecific(base) {} + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } +}; + +} // namespace + +#endif diff --git a/src/progs/gpsim/base/gpsim_debug.cpp b/src/progs/gpsim/base/gpsim_debug.cpp new file mode 100644 index 0000000..b2bcec5 --- /dev/null +++ b/src/progs/gpsim/base/gpsim_debug.cpp @@ -0,0 +1,282 @@ +/*************************************************************************** + * 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 "gpsim_debug.h" + +#include <signal.h> +#include <qregexp.h> + +#include "devices/list/device_list.h" +#include "devices/pic/base/pic_register.h" +#include "coff/base/text_coff.h" +#include "progs/manager/debug_manager.h" + +//---------------------------------------------------------------------------- +GPSim::Debugger::Debugger(Programmer &programmer) + : ::Debugger::PicBase(programmer), _nbBreakpoints(0) +{} + +bool GPSim::Debugger::internalInit() +{ + if ( !hardware()->execute("processor pic" + device()->name().lower(), true) ) return false; + if ( _inputType==PURL::Cod ) return hardware()->execute("load s " + _filename, true); + Q_ASSERT( _inputType==PURL::Hex ); + return hardware()->execute("load h " + _filename, true); +} + +bool GPSim::Debugger::internalRun() +{ + return hardware()->execute("run", false); +} + +bool GPSim::Debugger::hardHalt() +{ + log(Log::LineType::Warning, i18n("Failed to halt target: kill process.")); + _programmer.disconnectHardware(); + return true; +} + +bool GPSim::Debugger::softHalt(bool &success) +{ + success = hardware()->signal(SIGINT, true); + return true; +} + +bool GPSim::Debugger::internalStep() +{ + return hardware()->execute("step", true); +} + +bool GPSim::Debugger::setBreakpoints(const QValueList<Address> &list) +{ + for (uint i=0; i<_nbBreakpoints; i++) + if ( !hardware()->execute("clear " + QString::number(i), true) ) return false; + for (uint i=0; i<uint(list.count()); i++) + if ( !hardware()->execute("break e 0x" + toHex(list[i], nbChars(list[i].toUInt())), true) ) return false; + _nbBreakpoints = list.count(); + return true; +} + +bool GPSim::Debugger::internalReset() +{ + if ( _programmer.state()==::Programmer::Running && !halt() ) return false; + return hardware()->execute("reset", true); +} + +bool GPSim::Debugger::updateState() +{ + if ( hardware()->isReady() ) _programmer.setState(::Programmer::Halted); + else _programmer.setState(::Programmer::Running); + return true; +} + +bool GPSim::Debugger::findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const +{ + QRegExp rexp(pattern); + uint i = 0; + for (; i<uint(lines.count()); i++) { + int offset = 0; + for (;;) { + offset = rexp.search(lines[i], offset, QRegExp::CaretAtOffset); + if ( offset==-1 || rexp.cap(1)==label ) break; + offset += rexp.cap(0).length(); + } + if ( offset!=-1 ) break; + } + if ( i==uint(lines.count()) ) return false; + value = rexp.cap(2); + return true; +} + +bool GPSim::Debugger::readWreg(BitValue &value) +{ + // #### only known for version 4 and 11 + if ( hardware()->version()<=VersionData(0, 21, 7) || hardware()->version()>=VersionData(0, 22, 0) ) + return getRegister("W", value); + QStringList lines; + if ( !hardware()->execute("dump s", true, &lines) ) return false; + QString w = (_coff->symbol("_WREG") ? "_WREG" : "W"); + QString s; + if ( !findRegExp(lines, "^\\s*[0-9A-Fa-f]+\\s+(\\w+)\\s*=\\s*([0-9A-Fa-f]+)", w, s) ) { + log(Log::LineType::Error, i18n("Error reading register \"%1\"").arg(w)); + return false; + } + value = fromHex(s, 0); + return true; +} + +bool GPSim::Debugger::getRegister(const QString &name, BitValue &value) +{ + QStringList lines; + QRegExp r; + if ( hardware()->version()<VersionData(0, 22, 0) ) { + if ( !hardware()->execute("x " + name, true, &lines) ) return false; + r.setPattern("\\w+\\s*[][\\w]+\\s*=\\s*(?:0x|)([0-9A-Fa-f]+)(?:\\W.*|)"); + } else { + if ( !hardware()->execute(name, true, &lines) ) return false; + r.setPattern("[^=]*=\\s*(?:0x|\\$)([0-9A-Fa-f]+)(?:\\W.*|)"); + } + uint i = 0; + for (; i<uint(lines.count()); i++) + if ( r.exactMatch(lines[i]) ) break; + if ( i==uint(lines.count()) ) { + log(Log::LineType::Error, i18n("Error reading register \"%1\"").arg(name)); + return false; + } + value = fromHex(r.cap(1), 0); + return true; +} + +bool GPSim::Debugger::getRegister(Address address, BitValue &value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString name = toHex(address, rdata.nbCharsAddress()); + if ( hardware()->version()<VersionData(0, 22, 0) ) return getRegister("0x" + name, value); + return getRegister(QString("ramData[$%1]").arg(name), value); +} + +bool GPSim::Debugger::readRegister(const Register::TypeData &data, BitValue &value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return readWreg(value); + if ( data.name()=="PC" ) return getRegister("pc", value); + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return readWreg(value); + if ( !name.isEmpty() ) return getRegister(name.lower(), value); + return getRegister(data.address(), value); +} + +bool GPSim::Debugger::setRegister(const QString &name, BitValue value) +{ + if ( hardware()->version()<VersionData(0, 22, 0) ) { + log(Log::LineType::Warning, i18n("Writing registers is not supported by this version of gpsim")); + return true; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("%1 = %2").arg(name).arg(toHexLabel(value, rdata.nbChars())); + return hardware()->execute(s, true); +} + +bool GPSim::Debugger::setRegister(Address address, BitValue value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("ramData[$%1]").arg(toHex(address, rdata.nbCharsAddress())); + return setRegister(s, value); +} + +bool GPSim::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return writeWreg(value); + if ( data.name()=="PC" ) { + log(Log::LineType::Warning, i18n("Writing PC is not supported by gpsim")); + return true; + } + Q_ASSERT(false); + return false; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString name = rdata.sfrNames[data.address()]; + if ( !name.isEmpty() ) return setRegister(name.lower(), value); + return setRegister(data.address(), value); +} + +bool GPSim::Debugger::writeWreg(BitValue value) +{ + return setRegister("W", value); +} + +bool GPSim::Debugger::updatePortStatus(uint index, QMap<uint, Device::PortBitData> &bits) +{ + for (uint i=0; i<Device::MAX_NB_PORT_BITS; i++) { + if ( !device()->registersData().hasPortBit(index, i) ) continue; + QString name = device()->registersData().portName(index).lower() + QString::number(i); + QStringList lines; + if ( !hardware()->execute("symbol " + name, true, &lines) ) return false; + QString pattern = "^(\\w+)=([^\\s])+\\s*", value; + if ( !findRegExp(lines, pattern, "bitState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading state of IO bit: %1").arg(name)); + return false; + } + switch (value[0].latin1()) { + case 'H': + case '1': bits[i].state = Device::High; break; + case 'L': + case '0': bits[i].state = Device::Low; break; + case 'W': bits[i].state = Device::WeakPullUp; break; + case 'w': bits[i].state = Device::WeakPullDown; break; + case 'Z': bits[i].state = Device::HighImpedance; break; + case 'X': bits[i].state = Device::Unknown; break; + default: + bits[i].state = Device::Unknown; + log(Log::LineType::Warning, i18n("Unknown state for IO bit: %1 (%2)").arg(name).arg(value)); + break; + } + if ( !findRegExp(lines, pattern, "Driving", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].driving = ( value[0]=='1' ); + if (bits[i].driving) { + if ( !findRegExp(lines, pattern, "drivingState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivingState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivenState = Device::IoUnknown; + } else { + if ( !findRegExp(lines, pattern, "drivenState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driven state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivenState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivingState = Device::IoUnknown; + } + } + return true; +} + +//---------------------------------------------------------------------------- +QString GPSim::Group::statusLabel() const +{ + return i18n("GPSim (4MHz)"); // #### FIXME: add config +} + +void GPSim::Group::initSupported() +{ + ProcessManager manager(0); + if ( !manager.start() ) return; + VersionData version; + if ( !manager.getVersion(version) ) return; + bool oldGpsim = ( version<VersionData(0, 21, 11) ); + if ( !manager.sendCommand("processor list", true) ) return; + QStringList devices = QStringList::split(" ", manager.process().sout().join(" ")); + for (uint i=0; i<uint(devices.count()); i++) { + QString s = devices[i].upper(); + if ( s.startsWith("PIC") ) s = s.mid(3); + const Pic::Data *data = static_cast<const Pic::Data *>(Device::lister().data(s)); + if (data) { + if ( data->architecture()==Pic::Architecture::P18F && oldGpsim ) continue; + addDevice(data->name(), data, ::Group::Support::Tested); + } + } +} + +Programmer::Hardware *GPSim::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *GPSim::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/gpsim/base/gpsim_debug.h b/src/progs/gpsim/base/gpsim_debug.h new file mode 100644 index 0000000..ad838b2 --- /dev/null +++ b/src/progs/gpsim/base/gpsim_debug.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * 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 GPSIM_DEBUG_H +#define GPSIM_DEBUG_H + +#include "gpsim.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/pic/prog/pic_debug.h" + +namespace GPSim +{ +//----------------------------------------------------------------------------- +class Programmer : public ::Programmer::PicBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "gpsim_programmer") {} + +private: + virtual VersionData minVersion() const { return VersionData(0, 21, 0); } + virtual bool verifyDeviceId() { return true; } + virtual bool checkErase() { return false; } + virtual bool internalErase(const Device::MemoryRange &) { return false; } + virtual bool checkRead() { return false; } + virtual bool internalRead(Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkProgram(const Device::Memory &) { return false; } + virtual bool internalProgram(const Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkVerify() { return false; } + virtual bool internalVerify(const Device::Memory &, const Device::MemoryRange &, ::Programmer::VerifyActions) { return false; } +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(Programmer &programmer); + virtual bool setBreakpoints(const QValueList<Address> &list); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + virtual bool updatePortStatus(uint index, QMap<uint, Device::PortBitData> &bits); + +private: + uint _nbBreakpoints; + + bool findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const; + bool getRegister(const QString &name, BitValue &value); + bool setRegister(const QString &name, BitValue value); + bool getRegister(Address address, BitValue &value); + bool setRegister(Address address, BitValue value); + Hardware *hardware() { return static_cast<Hardware *>(_programmer.hardware()); } + const Pic::Data *device() const { return static_cast<const Pic::Data *>(_programmer.device()); } + virtual bool internalInit(); + virtual bool updateState(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + bool readWreg(BitValue &value); + bool writeWreg(BitValue value); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "gpsim"; } + virtual QString label() const { return i18n("GPSim"); } + virtual QString statusLabel() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Debugger | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType) const { return false; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 100; } + virtual bool isInputFileTypeSupported(PURL::FileType type) const { return ( type==PURL::Cod || type==PURL::Hex ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast<Programmer &>(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/gpsim/gpsim.pro b/src/progs/gpsim/gpsim.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/gpsim/gpsim.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/gpsim/gui/Makefile.am b/src/progs/gpsim/gui/Makefile.am new file mode 100644 index 0000000..d63f4a8 --- /dev/null +++ b/src/progs/gpsim/gui/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libgpsimui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libgpsimui.la +libgpsimui_la_SOURCES = gpsim_group_ui.cpp diff --git a/src/progs/gpsim/gui/gpsim_group_ui.cpp b/src/progs/gpsim/gui/gpsim_group_ui.cpp new file mode 100644 index 0000000..3949b8e --- /dev/null +++ b/src/progs/gpsim/gui/gpsim_group_ui.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 "gpsim_group_ui.h" + +#include <qtimer.h> + +#include "progs/base/prog_group.h" +#include "progs/gpsim/base/gpsim.h" + +//---------------------------------------------------------------------------- +GPSim::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + QLabel *label = new QLabel(i18n("Status:"), this); + addWidget(label, row,row, 0,0); + _status = new QLabel(this); + addWidget(_status, row,row, 1,1); + + QTimer::singleShot(0, this, SLOT(updateStatus())); +} + +void GPSim::ConfigWidget::updateStatus() +{ + VersionData version; + ProcessManager manager(0); + if ( !manager.start() ) _status->setText(i18n("Could not start \"gpsim\"")); + else if ( !manager.getVersion(version) || !version.isValid() ) _status->setText(i18n("Could not detect \"gpsim\" version")); + else _status->setText(i18n("Found version \"%1\"").arg(version.pretty())); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *GPSim::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} diff --git a/src/progs/gpsim/gui/gpsim_group_ui.h b/src/progs/gpsim/gui/gpsim_group_ui.h new file mode 100644 index 0000000..485aa69 --- /dev/null +++ b/src/progs/gpsim/gui/gpsim_group_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 GPSIM_GROUP_UI_H +#define GPSIM_GROUP_UI_H + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/prog_config_widget.h" + +namespace GPSim +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + +private slots: + void updateStatus(); + +private: + QLabel *_status; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/gui/Makefile.am b/src/progs/gui/Makefile.am new file mode 100644 index 0000000..7b32635 --- /dev/null +++ b/src/progs/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libprogui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogui.la +libprogui_la_SOURCES = prog_config_widget.cpp prog_group_ui.cpp \ + hardware_config_widget.cpp prog_config_center.cpp port_selector.cpp debug_config_center.cpp diff --git a/src/progs/gui/debug_config_center.cpp b/src/progs/gui/debug_config_center.cpp new file mode 100644 index 0000000..9286e3e --- /dev/null +++ b/src/progs/gui/debug_config_center.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "debug_config_center.h" + +#include <kiconloader.h> + +QPixmap Debugger::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_debugger", KIcon::Toolbar, KIcon::SizeMedium); +} diff --git a/src/progs/gui/debug_config_center.h b/src/progs/gui/debug_config_center.h new file mode 100644 index 0000000..a8e496e --- /dev/null +++ b/src/progs/gui/debug_config_center.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2007 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 DEBUG_CONFIG_CENTER_H +#define DEBUG_CONFIG_CENTER_H + +#include <qcheckbox.h> + +#include "common/gui/config_widget.h" +#include "progs/base/debug_config.h" + +namespace Debugger +{ + +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Debugging Options"); } + virtual QString title() const { return i18n("Debugging Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +} // namespace + +#endif diff --git a/src/progs/gui/hardware_config_widget.cpp b/src/progs/gui/hardware_config_widget.cpp new file mode 100644 index 0000000..8d82ddb --- /dev/null +++ b/src/progs/gui/hardware_config_widget.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** + * 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 "hardware_config_widget.h" + +#include <qlabel.h> +#include <kpushbutton.h> + +#include "progs/base/prog_config.h" +#include "devices/base/device_group.h" +#include "common/gui/misc_gui.h" + +//----------------------------------------------------------------------------- +Hardware::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit) + : QFrame(parent, "hardware_config_widget"), _edit(edit), _connected(false), _base(base) +{ + _hardware = 0; + + QHBoxLayout *top = new QHBoxLayout(this, 0, 10); + _mainVBox = new QVBoxLayout(top); + + if (edit) { + _editVBox = new QVBoxLayout(top); + top->setStretchFactor(_editVBox, 1); + } else _editVBox = 0; +} + +//----------------------------------------------------------------------------- +Hardware::EditDialog::EditDialog(ConfigWidget *cwidget, const QString &name, const Port::Description &pd, Data *data) + : KDialogBase(Plain, i18n("Edit and test hardware"), Ok|Cancel, Cancel, cwidget, "hardware_edit_dialog", true, true), + _cwidget(cwidget), _savedName(name), _oldData(data) +{ + setButtonOK(i18n("Save")); + setButtonCancel(i18n("Close")); + + QGridLayout *grid = new QGridLayout(plainPage(), 1, 1, 0, 10); + grid->setColStretch(2, 1); + + QLabel *label = new QLabel(i18n("Hardware name:"), plainPage()); + grid->addWidget(label, 0, 0); + _name = new QLineEdit(name, plainPage()); + grid->addWidget(_name, 0, 1); + + label = new QLabel(i18n("%1 at %2:").arg(pd.type.label()).arg(pd.device), plainPage()); + grid->addWidget(label, 1, 0); + label = new QLabel(plainPage()); + grid->addWidget(label, 1, 1); + + _hc = cwidget->createHardwareConfigWidget(plainPage(), true); + grid->addMultiCellWidget(_hc, 2,2, 0,2); + + grid->setRowStretch(3, 1); + + bool ok = _hc->set(pd, *data); + label->setText(ok ? i18n("Connected") : i18n("Not Connected")); +} + +void Hardware::EditDialog::slotOk() +{ + if ( _name->text().isEmpty() ) { + MessageBox::sorry(i18n("Could not save configuration: hardware name is empty."), Log::Show); + return; + } + if ( _cwidget->_config->isStandardHardware(_name->text()) ) { + MessageBox::sorry(i18n("The hardware name is already used for a standard hardware."), Log::Show); + return; + } + QStringList names = _cwidget->_config->hardwareNames(PortType::Nb_Types); // all hardwares + if ( names.contains(_name->text()) ) { + if ( !MessageBox::askContinue(i18n("Do you want to overwrite this custom hardware \"%1\"?").arg(_name->text()), + KStdGuiItem::save()) ) return; + } + delete _oldData; + _oldData = _hc->data(); + _cwidget->_config->writeCustomHardware(_name->text(), *_oldData); + _savedName = _name->text(); + KDialogBase::accept(); +} + +void Hardware::EditDialog::slotCancel() +{ + Data *data = _hc->data(); + bool equal = _oldData->isEqual(*data); + delete data; + if ( !equal && !MessageBox::askContinue(i18n("Closing will discard changes you have made. Close anyway?"), KStdGuiItem::close()) ) + return; + KDialogBase::reject(); +} + +//----------------------------------------------------------------------------- +Hardware::ConfigWidget::ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent) + : ::Programmer::ConfigWidget(base->group(), parent), _base(base), _config(config), _hc(0) +{ +// programmer combo + uint row = numRows(); + _configCombo = new QComboBox(this); + connect(_configCombo, SIGNAL(activated(int)), SLOT(configChanged(int))); + addWidget(_configCombo, row,row, 0,0); + row++; + +// hardware config + QHBoxLayout *hbox = new QHBoxLayout(10); + _hbox = new QHBoxLayout(10); + hbox->addLayout(_hbox); + addLayout(hbox, row,row, 0,1); + row++; + +// comment + _comment = new KTextBrowser(this); + addWidget(_comment, row,row, 0,1); + row++; + +// buttons + QVBoxLayout *vbox = new QVBoxLayout(hbox); + _editButton = new KPushButton(this); + connect(_editButton, SIGNAL(clicked()), SLOT(editClicked())); + vbox->addWidget(_editButton); + _deleteButton = new KPushButton(i18n("Delete"), this); + connect(_deleteButton, SIGNAL(clicked()), SLOT(deleteClicked())); + vbox->addWidget(_deleteButton); + vbox->addStretch(1); +} + +void Hardware::ConfigWidget::saveConfig() +{ + ::Programmer::ConfigWidget::saveConfig(); + _config->writeCurrentHardware(_hc->portDescription().type, _names[_configCombo->currentItem()]); +} + +void Hardware::ConfigWidget::configChanged(int i) +{ + set(_hc->portDescription(), i); +} + +bool Hardware::ConfigWidget::set(const Port::Description &pd, uint i) +{ + Data *hd = _config->hardwareData(_names[i]); + if ( _hc==0 ) { + _hc = createHardwareConfigWidget(this, false); + _hc->show(); + _hbox->addWidget(_hc); + } + bool ok = _hc->set(pd, *hd); + delete hd; + QString s = _config->comment(_names[i]); + if ( s.isEmpty() ) _comment->hide(); + else { + _comment->setText(s); + _comment->show(); + } + bool custom = !_config->isStandardHardware(_names[i]); + _editButton->setText(custom ? i18n("Edit/Test...") : i18n("New/Test...")); + _deleteButton->setEnabled(custom); + return ok; +} + +bool Hardware::ConfigWidget::setPort(const ::Programmer::HardwareDescription &hd) +{ + updateList(hd.port.type); + int i = _names.findIndex(_config->currentHardware(hd.port.type)); + if ( i!=-1 ) _configCombo->setCurrentItem(i); + return set(hd.port, _configCombo->currentItem()); +} + +void Hardware::ConfigWidget::updateList(PortType type) +{ + _configCombo->clear(); + _names = _config->hardwareNames(type); + for (uint i=0; i<_names.count(); i++) { + bool standard = _config->isStandardHardware(_names[i]); + QString s = (standard ? _config->label(_names[i]) : i18n("%1 <custom>").arg(_names[i])); + _configCombo->insertItem(s); + } +} + +void Hardware::ConfigWidget::editClicked() +{ + QString name = _names[_configCombo->currentItem()]; + QString cname = (_config->isStandardHardware(name) ? QString::null : name); + Port::Description pd = _hc->portDescription(); + EditDialog *hcd = new EditDialog(this, cname, pd, _hc->data()); + int res = hcd->exec(); + if ( res==QDialog::Rejected ) return; + updateList(pd.type); + int index = _names.findIndex(hcd->savedName()); + _configCombo->setCurrentItem(index); + configChanged(_configCombo->currentItem()); +} + +void Hardware::ConfigWidget::deleteClicked() +{ + QString name = _names[_configCombo->currentItem()]; + if ( !MessageBox::askContinue(i18n("Do you want to delete custom hardware \"%1\"?").arg(name), + KStdGuiItem::del()) ) return; + _config->deleteCustomHardware(name); + updateList(_hc->portDescription().type); + configChanged(_configCombo->currentItem()); +} diff --git a/src/progs/gui/hardware_config_widget.h b/src/progs/gui/hardware_config_widget.h new file mode 100644 index 0000000..d373990 --- /dev/null +++ b/src/progs/gui/hardware_config_widget.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef HARDWARE_CONFIG_WIDGET +#define HARDWARE_CONFIG_WIDGET + +#include <qlineedit.h> +#include <qcombobox.h> +#include <kdialogbase.h> +#include <ktextbrowser.h> + +#include "progs/base/hardware_config.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_specific.h" + +namespace Hardware +{ + +//----------------------------------------------------------------------------- +class HConfigWidget : public QFrame +{ +Q_OBJECT +public: + HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit); + virtual ~HConfigWidget() { delete _hardware; } + virtual bool set(const Port::Description &pd, const Data &data) = 0; + virtual Data *data() const = 0; + Port::Description portDescription() const { return _hardware->portDescription(); } + +protected: + ::Programmer::Hardware *_hardware; + QVBoxLayout *_mainVBox, *_editVBox; + bool _edit, _connected; + ::Programmer::Base &_base; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget; + +class EditDialog : public KDialogBase +{ +Q_OBJECT +public: + EditDialog(ConfigWidget *parent, const QString &name, const Port::Description &pd, Data *data); + QString savedName() const { return _savedName; } + +private slots: + virtual void slotOk(); + virtual void slotCancel(); + +private: + ConfigWidget *_cwidget; + QString _savedName; + Data *_oldData; + HConfigWidget *_hc; + QLineEdit *_name; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget : public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent); + virtual ~ConfigWidget() { delete _base; } + virtual void saveConfig(); + virtual bool setPort(const ::Programmer::HardwareDescription &hd); + virtual HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const = 0; + +private slots: + void editClicked(); + void deleteClicked(); + void configChanged(int i); + +protected: + ::Programmer::Base *_base; + +private: + Config *_config; + QStringList _names; + HConfigWidget *_hc; + QPushButton *_editButton, *_deleteButton; + QComboBox *_configCombo; + KTextBrowser *_comment; + QHBoxLayout *_hbox; + + void updateList(PortType type); + bool set(const Port::Description &pd, uint i); + + friend class EditDialog; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/port_selector.cpp b/src/progs/gui/port_selector.cpp new file mode 100644 index 0000000..2aaaabf --- /dev/null +++ b/src/progs/gui/port_selector.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * 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 "port_selector.h" + +#include <qtimer.h> +#include <ktextbrowser.h> + +#include "common/port/serial.h" +#include "common/port/parallel.h" +#include "common/global/about.h" +#include "common/gui/purl_gui.h" +#include "progs/base/prog_config.h" + +const char * const PortSelector::LABELS[PortType::Nb_Types] = { + I18N_NOOP("Serial"), I18N_NOOP("Parallel"), I18N_NOOP("USB") +}; + +PortSelector::PortSelector(QWidget *parent) + : QFrame(parent, "port_selector"), _group(0), _main(0) +{ + _top = new QGridLayout(this, 1, 1, 0, 10); + _top->setRowStretch(1, 1); + + _bgroup = new QButtonGroup; + connect(_bgroup, SIGNAL(clicked(int)), SIGNAL(changed())); +} + +void PortSelector::setGroup(const Programmer::Group &group) +{ + _group = &group; + delete _main; + _main = new QWidget(this); + _top->addWidget(_main, 0, 0); + _grid = new QGridLayout(_main, 1, 1, 0, 10); + _grid->setColStretch(3, 1); + FOR_EACH(PortType, type) { + _combos[type.type()] = 0; + _status[type.type()] = 0; + if ( !group.isPortSupported(type) ) continue; + Port::Description pd(type, Programmer::GroupConfig::portDevice(group, type)); + addPortType(pd); + } + _bgroup->setButton(Programmer::GroupConfig::portType(group).type()); + _main->show(); +} + +void PortSelector::addPortType(const Port::Description &pd) +{ + QString noDeviceMessage, notAvailableMessage; + switch (pd.type.type()) { + case PortType::Serial: + noDeviceMessage = i18n("Your computer might not have any serial port."); + break; + case PortType::Parallel: + noDeviceMessage = i18n("Your computer might not have any parallel port " + "or the /dev/parportX device has not been created.<br>" + "Use \"mknod /dev/parport0 c 99 0\" to create it<br>" + "and \"chmod a+rw /dev/parport0\" to make it RW enabled."); + notAvailableMessage = i18n("Piklab has been compiled without support for parallel port."); + break; + case PortType::USB: + notAvailableMessage = i18n("Piklab has been compiled without support for USB port."); + break; + case PortType::Nb_Types: Q_ASSERT(false); break; + } + + QRadioButton *rb = new QRadioButton(i18n(LABELS[pd.type.type()]), _main); + _bgroup->insert(rb, pd.type.type()); + if ( _bgroup->count()==1 ) _bgroup->setButton(pd.type.type()); + _grid->addWidget(rb, 3*(_bgroup->count()-1), 0); + _status[pd.type.type()] = new QLabel(_main); + _grid->addWidget(_status[pd.type.type()], 3*(_bgroup->count()-1), 2); + + QStringList list = Port::probedDeviceList(pd.type); + bool noDevice = ( list.isEmpty() && pd.type.data().withDevice ); + bool notAvailable = !Port::isAvailable(pd.type); + rb->setEnabled(!notAvailable); + if ( noDevice || notAvailable ) { + KTextBrowser *comment = new KTextBrowser(_main); + QString text = (notAvailable ? notAvailableMessage : noDeviceMessage); + text += "<p>"; + text += i18n("<a href=\"%1\">See Piklab homepage for help</a>.").arg(Piklab::URLS[Piklab::Support]); + comment->setText(text); + _grid->addMultiCellWidget(comment, 3*(_bgroup->count()-1)+1,3*(_bgroup->count()-1)+1, 0,3); + } + + if (pd.type.data().withDevice) { + _combos[pd.type.type()] = new QComboBox(true, _main); + for (uint i=0; i<list.count(); i++) _combos[pd.type.type()]->insertItem(list[i]); + if ( !pd.device.isEmpty() && !list.contains(pd.device) ) _combos[pd.type.type()]->insertItem(pd.device); + _combos[pd.type.type()]->setCurrentText(pd.device); + connect(_combos[pd.type.type()], SIGNAL(activated(int)), SIGNAL(changed())); + connect(_combos[pd.type.type()], SIGNAL(textChanged(const QString &)), SLOT(textChanged())); + _grid->addWidget(_combos[pd.type.type()], 3*(_bgroup->count()-1), 1); + } +} + +void PortSelector::setStatus(PortType ptype, const QString &message) +{ + _pending = false; + FOR_EACH(PortType, type) { + if ( _status[type.type()]==0 ) continue; + if ( type!=ptype ) _status[type.type()]->hide(); + else { + _status[type.type()]->show(); + _status[type.type()]->setText(message); + } + } +} + +QString PortSelector::device(PortType type) const +{ + if ( type==PortType::Nb_Types || _combos[type.type()]==0 || !type.data().withDevice ) return QString::null; + return _combos[type.type()]->currentText(); +} + +void PortSelector::saveConfig() +{ + Programmer::GroupConfig::writePortType(*_group, type()); + FOR_EACH(PortType, type) { + if ( !_group->isPortSupported(type) ) continue; + Programmer::GroupConfig::writePortDevice(*_group, type, device(type)); + } +} + +PortType PortSelector::type() const +{ + if ( _bgroup->count()==0 ) return PortType::Nb_Types; + return PortType::Type(_bgroup->selectedId()); +} + +void PortSelector::textChanged() +{ + if (_pending) return; + _status[type().type()]->hide(); + _pending = true; + QTimer::singleShot(1000, this, SIGNAL(changed())); +} diff --git a/src/progs/gui/port_selector.h b/src/progs/gui/port_selector.h new file mode 100644 index 0000000..6304d1a --- /dev/null +++ b/src/progs/gui/port_selector.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * 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 PORT_SELECTOR_H +#define PORT_SELECTOR_H + +#include <qradiobutton.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qbuttongroup.h> +#include <qlabel.h> + +#include "common/port/port.h" +namespace Programmer { class Group; } + +class PortSelector : public QFrame +{ + Q_OBJECT +public: + PortSelector(QWidget *parent); + void setGroup(const Programmer::Group &group); + Port::Description portDescription() const { return Port::Description(type(), device(type())); } + void saveConfig(); + void setStatus(PortType type, const QString &message); + +signals: + void changed(); + +private slots: + void textChanged(); + +private: + const Programmer::Group *_group; + QGridLayout *_top, *_grid; + QWidget *_main; + QButtonGroup *_bgroup; + QComboBox *_combos[PortType::Nb_Types]; + QLabel *_status[PortType::Nb_Types]; + bool _pending; + static const char * const LABELS[PortType::Nb_Types]; + + void addPortType(const Port::Description &pd); + PortType type() const; + QString device(PortType type) const; +}; + +#endif diff --git a/src/progs/gui/prog_config_center.cpp b/src/progs/gui/prog_config_center.cpp new file mode 100644 index 0000000..3210921 --- /dev/null +++ b/src/progs/gui/prog_config_center.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 "prog_config_center.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qwidgetstack.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <qtimer.h> +#include <qtabwidget.h> +#include <kiconloader.h> + +#include "progs/list/prog_list.h" +#include "prog_config_widget.h" +#include "prog_group_ui.h" +#include "libgui/global_config.h" +#include "port_selector.h" +#include "libgui/main_global.h" + +//---------------------------------------------------------------------------- +QPixmap Programmer::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +//---------------------------------------------------------------------------- +Programmer::SelectConfigWidget::SelectConfigWidget() +{ + uint row = 0; + +// programmer type + QLabel *label = new QLabel(i18n("Programmer in use:"), this); + addWidget(label, row,row, 0,0); + _combo = new KeyComboBox<QString>(this); + connect(_combo->widget(), SIGNAL(activated(int)), SLOT(programmerChanged())); + addWidget(_combo->widget(), row,row, 1,1); + row++; + +// tab widget + _tabWidget = new QTabWidget(this); + addWidget(_tabWidget, row,row, 0,2); + row++; + + // port selector + _portSelectorContainer = new Container; + _portSelectorContainer->setMargin(10); + _portSelector = new PortSelector(_portSelectorContainer); + connect(_portSelector, SIGNAL(changed()), SLOT(portChanged())); + _portSelectorContainer->addWidget(_portSelector, 0,0, 0,0); + + // specific programmer config + _stack = new KeyWidgetStack<QString>(_tabWidget); + static_cast<QFrame *>(_stack->widget())->setMargin(10); + KIconLoader loader; + QPixmap icon = loader.loadIcon("configure", KIcon::Small); + _tabWidget->addTab(_stack->widget(), icon, i18n("Specific")); + ::Programmer::Lister::ConstIterator it; + for (it=::Programmer::lister().begin(); it!=::Programmer::lister().end(); ++it) { + _combo->appendItem(it.key(), it.data()->label()); + ::Programmer::ConfigWidget *pcw = static_cast<const ::Programmer::GroupUI *>(it.data()->gui())->createConfigWidget(_stack->widget()); + pcw->loadConfig(); + _stack->appendItem(it.key(), pcw); + } + + // init + _combo->setCurrentItem(GlobalConfig::programmerGroup().name()); + _stack->setCurrentItem(GlobalConfig::programmerGroup().name()); + QTimer::singleShot(0, this, SLOT(programmerChanged())); +} + +void Programmer::SelectConfigWidget::portChanged() +{ + ::BusyCursor bc; // can take a few seconds to connect programmer... + HardwareDescription hd; + hd.port = _portSelector->portDescription(); + ::Hardware::Config *config = Main::programmerGroup().hardwareConfig(); + if (config) hd.name = config->currentHardware(hd.port.type); + delete config; + QWidget *w = _stack->item(_combo->currentItem()); + bool ok = static_cast< ::Programmer::ConfigWidget *>(w)->setPort(hd); + _portSelector->setStatus(hd.port.type, ok ? i18n("Connection: Ok") : i18n("Connection: Error")); +} + +QPixmap Programmer::SelectConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +void Programmer::SelectConfigWidget::saveConfig() +{ + _portSelector->saveConfig(); + QString key = _combo->currentItem(); + static_cast<ConfigWidget *>(_stack->item(key))->saveConfig(); + GlobalConfig::writeProgrammerGroup(*::Programmer::lister().group(key)); +} + +void Programmer::SelectConfigWidget::programmerChanged() +{ + QString key = _combo->currentItem(); + const ::Programmer::Group &group = *::Programmer::lister().group(key); + bool isHardware = !group.isSoftware(); + bool hasTab = ( _tabWidget->indexOf(_portSelectorContainer)!=-1 ); + if (isHardware) { + if ( !hasTab ) { + KIconLoader loader; + QPixmap icon = loader.loadIcon("connect_creating", KIcon::Small); + _tabWidget->insertTab(_portSelectorContainer, icon, i18n("Port Selection"), 0); + } + } else if (hasTab) _tabWidget->removePage(_portSelectorContainer); + _portSelector->setGroup(group); + _stack->setCurrentItem(key); + if (isHardware) QTimer::singleShot(0, this, SLOT(portChanged())); +} diff --git a/src/progs/gui/prog_config_center.h b/src/progs/gui/prog_config_center.h new file mode 100644 index 0000000..ea5ee6d --- /dev/null +++ b/src/progs/gui/prog_config_center.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * 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 PROG_CONFIG_CENTER_H +#define PROG_CONFIG_CENTER_H + +#include <qcheckbox.h> + +#include "common/gui/config_widget.h" +#include "common/gui/key_gui.h" +#include "progs/base/prog_config.h" +class Container; +class PortSelector; + +namespace Programmer +{ +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Programmer Options"); } + virtual QString title() const { return i18n("Programmer Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +//---------------------------------------------------------------------------- +class SelectConfigWidget : public ::ConfigWidget +{ +Q_OBJECT +public: + SelectConfigWidget(); + virtual void loadConfig() {} + virtual QString header() const { return i18n("Programmer Selection"); } + virtual QString title() const { return i18n("Programmer Selection"); } + virtual QPixmap pixmap() const; + +public slots: + virtual void saveConfig(); + +private slots: + void programmerChanged(); + void portChanged(); + +private: + KeyComboBox<QString> *_combo; + PortSelector *_portSelector; + KeyWidgetStack<QString> *_stack; + Container *_portSelectorContainer; + QTabWidget *_tabWidget; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_config_widget.cpp b/src/progs/gui/prog_config_widget.cpp new file mode 100644 index 0000000..be767c2 --- /dev/null +++ b/src/progs/gui/prog_config_widget.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * 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 "prog_config_widget.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <kurlrequester.h> + +#include "progs/base/prog_config.h" +#include "progs/base/prog_group.h" + +Programmer::ConfigWidget::ConfigWidget(const Group &group, QWidget *parent) + : ::ConfigWidget(parent), _group(group) +{ + if ( group.properties() & NeedDeviceSpecificFirmware ) { + uint row = numRows(); + QLabel *label = new QLabel(i18n("Firmware directory:"), this); + addWidget(label, row,row, 0,0); + _firmwareDir = new KURLRequester(this); + _firmwareDir->setMode(KFile::Directory | KFile::ExistingOnly); + addWidget(_firmwareDir, row,row, 1,1); + } else _firmwareDir = 0; +} + +void Programmer::ConfigWidget::loadConfig() +{ + if (_firmwareDir) _firmwareDir->setURL(GroupConfig::firmwareDirectory(_group)); +} + +void Programmer::ConfigWidget::saveConfig() +{ + if (_firmwareDir) GroupConfig::writeFirmwareDirectory(_group, _firmwareDir->url()); +} + +bool Programmer::ConfigWidget::setPort(const HardwareDescription &hd) +{ + return _group.checkConnection(hd); +} diff --git a/src/progs/gui/prog_config_widget.h b/src/progs/gui/prog_config_widget.h new file mode 100644 index 0000000..d201cea --- /dev/null +++ b/src/progs/gui/prog_config_widget.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * 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 PROG_CONFIG_WIDGET +#define PROG_CONFIG_WIDGET + +class QCheckBox; +class KURLRequester; + +#include "common/gui/config_widget.h" +#include "common/port/port.h" + +namespace Programmer +{ +class Group; +class HardwareDescription; + +class ConfigWidget: public ::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const Group &group, QWidget *parent); + virtual void loadConfig(); + const Group &group() const { return _group; } + virtual void saveConfig(); + virtual bool setPort(const HardwareDescription &hd); + +signals: + void updatePortStatus(bool ok); + +protected: + const Group &_group; + +private: + KURLRequester *_firmwareDir; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_group_ui.cpp b/src/progs/gui/prog_group_ui.cpp new file mode 100644 index 0000000..14cf7b0 --- /dev/null +++ b/src/progs/gui/prog_group_ui.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * 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 "prog_group_ui.h" + +#include <klocale.h> +#include <kaction.h> +#include <kiconloader.h> + +#include "common/common/misc.h" +#include "common/global/purl.h" +#include "common/gui/purl_gui.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/prog_config.h" +#include "libgui/main_global.h" +#include "libgui/toplevel.h" +#include "devices/base/device_group.h" +#include "devices/pic/prog/pic_prog.h" + +//---------------------------------------------------------------------------- +Programmer::StandaloneMemoryCalibrationEditor::StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent) + : Pic::MemoryCalibrationEditor(0, const_cast<Pic::Memory &>(memory), parent) +{} + +void Programmer::StandaloneMemoryCalibrationEditor::init(bool first) +{ + Pic::MemoryCalibrationEditor::init(first); + KAction *action = new KAction(i18n("Read"), "reload", 0, this, SIGNAL(updateCalibration()), Main::toplevel().actionCollection()); + addAction(action); + action = new KAction(i18n("Regenerating..."), 0, 0, this, SIGNAL(regenerate()), Main::toplevel().actionCollection()); + addAction(action); +} + +//---------------------------------------------------------------------------- +Programmer::ButtonContainer::ButtonContainer(const QString &title, + QObject *receiver, const char *updateSlot, QWidget *parent) + : ::ButtonContainer(title, parent) +{ + if (receiver) button().appendAction(i18n("Read"), "reload", receiver, updateSlot); +} + +//---------------------------------------------------------------------------- +Programmer::AdvancedDialog::AdvancedDialog(Base &base, QWidget *parent, const char *name) + : Dialog(IconList, i18n("Advanced Dialog"), Close, Close, parent, name, true, false), + _base(base), _calEditor(0) +{ + // programmer + KIconLoader loader; + QPixmap pixmap = loader.loadIcon("piklab_burnchip", KIcon::Toolbar, KIcon::SizeMedium); + QFrame *page = addPage(i18n("Programmer"), _base.group().label(), pixmap); + QVBoxLayout *vbox = new QVBoxLayout(page); + _programmerContainer = new Container(page); + vbox->addWidget(_programmerContainer); + + Properties properties = _base.group().properties(); + uint row = _programmerContainer->numRows(); + if ( properties & HasFirmware ) { + _firmwareContainer = new ButtonContainer(i18n("Firmware"), this, SLOT(updateFirmware()), _programmerContainer); + _programmerContainer->addWidget(_firmwareContainer, row,row, 0,1); + if ( _base.group().properties() & CanUploadFirmware ) + _firmwareContainer->button().appendAction(i18n("Uploading..."), "piklab_burnchip", this, SLOT(uploadFirmware())); + QLabel *label = new QLabel(i18n("Version:"), _firmwareContainer); + _firmwareContainer->addWidget(label, 1,1, 0,0); + _firmwareLabel = new QLabel(_firmwareContainer); + _firmwareContainer->addWidget(_firmwareLabel, 1,1, 1,1); + row++; + } else { + _firmwareContainer = 0; + _firmwareLabel = 0; + } + + if ( _base.group().canReadVoltages() ) { + _voltagesContainer = new ButtonContainer(i18n("Voltages"), this, SLOT(updateVoltages()), _programmerContainer); + _programmerContainer->addWidget(_voltagesContainer, row,row, 0,1); + row++; + } else _voltagesContainer = 0; + + if ( properties & HasSelfTest ) { + _selfTestContainer = new ButtonContainer(i18n("Self-test"), this, SLOT(updateSelfTest()), _programmerContainer); + _programmerContainer->addWidget(_selfTestContainer, row,row, 0,1); + row++; + } else _selfTestContainer = 0; + + // calibration + pixmap = loader.loadIcon("configure", KIcon::Toolbar, KIcon::SizeMedium); + page = addPage(i18n("Calibration"), i18n("Calibration"), pixmap); + vbox = new QVBoxLayout(page); + _calibrationContainer = new Container(page); + vbox->addWidget(_calibrationContainer); + const Device::Data *data = Main::deviceData(); + QString s; + if ( data==0 ) s = i18n("No device selected."); + else if ( data->group().name()!="pic" || !static_cast<const Pic::Data *>(data)->isReadable(Pic::MemoryRangeType::Cal) ) + s = i18n("This device has no calibration information."); + else if ( !_base.group().isSupported(data->name()) ) s = i18n("The selected device is not supported by this programmer."); + else { + const ::Programmer::PicBase &pbase = static_cast<const ::Programmer::PicBase &>(_base); + _calEditor = new StandaloneMemoryCalibrationEditor(pbase.deviceMemory(), _calibrationContainer); + connect(_calEditor, SIGNAL(updateCalibration()), SLOT(updateCalibration())); + connect(_calEditor, SIGNAL(regenerate()), SLOT(regenerateCalibration())); + _calEditor->init(true); + _calEditor->setReadOnly(true); + _calibrationContainer->addWidget(_calEditor, 0,0, 0,0); + } + if ( !s.isEmpty() ) { + QLabel *label = new QLabel(s, _calibrationContainer); + _calibrationContainer->addWidget(label, 0,0, 0,0); + } +} + +bool Programmer::AdvancedDialog::connectProgrammer() +{ + _base.disconnectHardware(); + if ( !_base.connectHardware() ) { + MessageBox::sorry(i18n("Could not connect programmer."), Log::Show); + return false; + } + return true; +} + +bool Programmer::AdvancedDialog::ensureConnected() +{ + if ( (_base.state()==NotConnected || _base.state()==Running) && !connectProgrammer() ) return false; + return _base.setTargetPowerOn(!readConfigEntry(Config::TargetSelfPowered).toBool()); +} + +void Programmer::AdvancedDialog::updateFirmware() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readFirmwareVersion(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::uploadFirmware() +{ + PURL::Url url = PURL::getOpenUrl(":open_firmware", PURL::filter(PURL::Hex), this ,i18n("Open Firmware")); + if ( url.isEmpty() ) return; + ::BusyCursor bc; + if ( !connectProgrammer() ) return; + if ( _base.uploadFirmware(url) ) + MessageBox::information(i18n("Firmware uploaded successfully."), Log::Show); + else MessageBox::sorry(i18n("Error uploading firmware."), Log::Show); + updateFirmware(); +} + +void Programmer::AdvancedDialog::updateVoltages() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readVoltages(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateSelfTest() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.selfTest(false); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateCalibration() +{ + ::BusyCursor bc; + if ( ensureConnected() ) static_cast< ::Programmer::PicBase &>(_base).readCalibration(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::regenerateCalibration() +{ + MessageBox::sorry(i18n("Oscillator calibration regeneration is not available with the selected programmer."), Log::Show); +} + +void Programmer::AdvancedDialog::updateDisplay() +{ + if (_firmwareLabel) _firmwareLabel->setText(_base.firmwareVersion().pretty()); + if (_calEditor) _calEditor->updateDisplay(); +} diff --git a/src/progs/gui/prog_group_ui.h b/src/progs/gui/prog_group_ui.h new file mode 100644 index 0000000..cd97834 --- /dev/null +++ b/src/progs/gui/prog_group_ui.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROG_GROUP_UI_H +#define PROG_GROUP_UI_H + +#include "common/gui/container.h" +#include "common/gui/dialog.h" +#include "progs/base/prog_group.h" +#include "progs/base/generic_prog.h" +#include "devices/pic/gui/pic_memory_editor.h" +class Container; +class PopupButton; + +namespace Programmer +{ +class ConfigWidget; +class Base; +class Group; + +//---------------------------------------------------------------------------- +class StandaloneMemoryCalibrationEditor : public Pic::MemoryCalibrationEditor +{ +Q_OBJECT +public: + StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent); + virtual void init(bool first); + virtual bool hasAction(Device::Action) const { return false; } + +signals: + void updateCalibration(); + void regenerate(); +}; + +//---------------------------------------------------------------------------- +class ButtonContainer : public ::ButtonContainer +{ +Q_OBJECT +public: + ButtonContainer(const QString &title, QObject *receiver, const char *updateSlot, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public Dialog +{ +Q_OBJECT +public: + AdvancedDialog(Base &base, QWidget *parent, const char *name); + virtual void updateDisplay(); + +protected: + Base &_base; + Container *_programmerContainer, *_calibrationContainer; + ButtonContainer *_firmwareContainer, *_voltagesContainer, *_selfTestContainer; + Pic::MemoryCalibrationEditor *_calEditor; + bool connectProgrammer(); + bool ensureConnected(); + +protected slots: + void updateFirmware(); + void uploadFirmware(); + void updateVoltages(); + void updateSelfTest(); + void updateCalibration(); + virtual void regenerateCalibration(); + +private: + QLabel *_firmwareLabel; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Group::BaseGui +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const = 0; + virtual bool hasAdvancedDialog() const = 0; + virtual AdvancedDialog *createAdvancedDialog(Base &base, QWidget *parent) const = 0; +}; + +inline const ::Programmer::GroupUI &groupui(const ::Programmer::Base &base) { return static_cast<const ::Programmer::GroupUI &>(*base.group().gui()); } + +} // namespace + +#endif diff --git a/src/progs/icd1/Makefile.am b/src/progs/icd1/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/icd1/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/icd1/base/Makefile.am b/src/progs/icd1/base/Makefile.am new file mode 100644 index 0000000..3795dc5 --- /dev/null +++ b/src/progs/icd1/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libicd1.la +libicd1_la_SOURCES = icd1.cpp icd1_prog.cpp icd1_serial.cpp icd1_data.cpp +libicd1_la_DEPENDENCIES = icd1_data.cpp + +noinst_DATA = icd1.xml +icd1_data.cpp: ../xml/xml_icd1_parser icd1.xml + ../xml/xml_icd1_parser +CLEANFILES = icd1_data.cpp diff --git a/src/progs/icd1/base/base.pro b/src/progs/icd1/base/base.pro new file mode 100644 index 0000000..8ff4081 --- /dev/null +++ b/src/progs/icd1/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd1 +HEADERS += icd1.h icd1_data.h icd1_prog.h icd1_serial.h +SOURCES += icd1.cpp icd1_data.cpp icd1_prog.cpp icd1_serial.cpp diff --git a/src/progs/icd1/base/icd1.cpp b/src/progs/icd1/base/icd1.cpp new file mode 100644 index 0000000..8c2704a --- /dev/null +++ b/src/progs/icd1/base/icd1.cpp @@ -0,0 +1,197 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "icd1.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" + +//----------------------------------------------------------------------------- +Icd1::Hardware::Hardware(::Programmer::Base &base, const QString &portDevice) + : Icd::Hardware(base, new SerialPort(portDevice, base)) +{} + +bool Icd1::Hardware::internalConnect(const QString &mode) +{ + if ( !port()->open() ) return false; + if ( !port()->reset() ) return false; + if ( hasError() ) return false; + QByteArray a = toAscii(mode); + if ( !port()->send(a.data(), a.count()) ) return false; + QString s; + if ( !port()->receive(1, s) ) return false; + port()->setPinOn(Port::Serial::RTS, false, Port::PositiveLogic); + Port::msleep(1); + port()->setPinOn(Port::Serial::RTS, true, Port::PositiveLogic); + if ( s.upper()!=mode ) { + log(Log::LineType::Error, i18n("Failed to set port mode to '%1'.").arg(mode)); + return false; + } + return true; +} + +bool Icd1::Hardware::sendCommand(uint cmd, BitValue *res, uint timeout) +{ + if ( !port()->sendCommand(cmd) ) return false; + uchar byte; + if ( !port()->receiveByte((char &)byte, false, timeout) ) return false; + if (res) *res = byte << 8; + if ( !port()->receiveByte((char &)byte, true, timeout) ) return false; + if (res) *res += byte; + return true; +} + +bool Icd1::Hardware::readBlockCommand(uint nbBytes) +{ + Q_ASSERT( nbBytes<=0xFF ); + if ( !port()->sendCommand(0x7D00 + nbBytes) ) return false; + QByteArray a(nbBytes); + for (uint i=0; i<nbBytes; i++) + if ( !port()->receiveByte(*(a.data()+i), i!=0) ) return false; + _rx = QString(a); + return true; +} + +bool Icd1::Hardware::setTarget() +{ + return sendCommand(0x6300 + data(_base.device()->name()).part); +} + +bool Icd1::Hardware::getFirmwareVersion(VersionData &version) +{ + BitValue v1, v2; + if ( !sendCommand(0x7F00, &v1) || !sendCommand(0x7021, &v2) ) return false; + version = VersionData(v1.byte(1), v1.byte(0), v2.toUInt()); + return true; +} + +bool Icd1::Hardware::readVoltages(VoltagesData &voltages) +{ + if ( !sendCommand(0x7000) ) return false; + BitValue res; + if ( !sendCommand(0x701C, &res) ) return false; + voltages[Pic::TargetVdd].value = (2.050 / 256) * res.toUInt(); // voltage at AN0 pin + voltages[Pic::TargetVdd].value /= (4.7 / 14.7); // voltage at Vcc + log(Log::DebugLevel::Max, QString("Vdd: %1 %2").arg(toHexLabel(res, 4)).arg(voltages[Pic::TargetVdd].value)); + voltages[Pic::TargetVdd].error = false; + if ( !sendCommand(0x701D, &res) ) return false; + voltages[Pic::TargetVpp].value = (2.050 / 256) * res.byte(0); // voltage at AN1 pin + voltages[Pic::TargetVpp].value /= (10.0 / 110.0); // voltage at Vpp + log(Log::DebugLevel::Max, QString("Vpp: %1 %2").arg(toHexLabel(res, 4)).arg(voltages[Pic::TargetVpp].value)); + voltages[Pic::TargetVpp].error = false; + return sendCommand(0x7001); +} + +bool Icd1::Hardware::uploadFirmware(const Pic::Memory &memory) +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::setTargetReset(Pic::ResetMode mode) +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::selfTest() +{ + BitValue res; + if ( !sendCommand(0x700B, &res, 5000) ) return false; + if ( res!=0 ) { + log(Log::LineType::Warning, i18n("Self-test failed (returned value is %1)").arg(toLabel(res))); + return false; + } + return true; +} + +bool Icd1::Hardware::gotoMemory(Pic::MemoryRangeType type, uint offset) +{ + if ( !sendCommand(0x7000) ) return false; // start sequence + uint cmd = (type==Pic::MemoryRangeType::Eeprom ? 0x7006 : 0x7005); + if ( !sendCommand(cmd) ) return false; + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::UserId || type==Pic::MemoryRangeType::DeviceId ) { + Q_ASSERT( offset==0 ); + offset = device().range(type).start - Address(0x2000); + if ( !sendCommand(0xC000 + offset) ) return false; + } else if ( !sendCommand(0x2000 + offset) ) return false; + return true; +} + +bool Icd1::Hardware::readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + if ( !gotoMemory(type, wordOffset) ) return false; + for (uint i=0; i<data.count(); i++) if ( !sendCommand(0x7002, &data[i]) ) return false; + if ( !sendCommand(0x7001) ) return false; // end sequence + if (vdata) { + for (uint i=0; i<data.count(); i++) + if ( !verifyWord(wordOffset+i, data[i], type, *vdata) ) return false; + } + return true; +} + +bool Icd1::Hardware::writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) +{ + if ( !gotoMemory(type, wordOffset) ) return false; + for (uint i=0; i<data.count(); i++) if ( !sendCommand(0x8000 | data[i].toUInt()) ) return false; + if ( !sendCommand(0x7001) ) return false; // end sequence + return true; +} + +bool Icd1::Hardware::eraseAll() +{ + BitValue res; + if ( !sendCommand(0x7000) ) return false; // enable Vpp + if ( !sendCommand(0x7007, &res) ) return false; + if ( !sendCommand(0x7001) ) return false; // disable Vpp + if ( res!=0x3FFF ) { + log(Log::LineType::Error, i18n("Erase failed (returned value is %1)").arg(toHexLabel(res, 4))); + return false; + } + return true; +} + +bool Icd1::Hardware::haltRun() +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::step() +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::resumeRun() +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::writeRegister(Address address, BitValue value, uint nbBytes) +{ + Q_ASSERT( nbBytes==1 || nbBytes==2 ); + // #### TODO + return false; +} + +bool Icd1::Hardware::readRegister(Address address, BitValue &value, uint nbBytes) +{ + Q_ASSERT( nbBytes==1 || nbBytes==2 ); + // #### TODO + return false; +} + +BitValue Icd1::Hardware::getProgramCounter() +{ + // #### TODO + return 0; +} diff --git a/src/progs/icd1/base/icd1.h b/src/progs/icd1/base/icd1.h new file mode 100644 index 0000000..d1ae1d0 --- /dev/null +++ b/src/progs/icd1/base/icd1.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 ICD1_H +#define ICD1_H + +#include "progs/icd2/base/icd.h" +#include "icd1_data.h" +#include "icd1_serial.h" + +namespace Icd1 +{ +//----------------------------------------------------------------------------- +class Hardware : public Icd::Hardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + SerialPort *port() { return static_cast<SerialPort *>(_port); } + // initialization + virtual bool uploadFirmware(const Pic::Memory &memory); + virtual bool setTarget(); + +// status + virtual bool getFirmwareVersion(VersionData &version); + virtual bool readVoltages(VoltagesData &voltages); + virtual bool setTargetReset(Pic::ResetMode mode); + bool selfTest(); + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data); + virtual bool eraseAll(); + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes); + virtual bool writeRegister(Address address, BitValue value, uint nbBytes); + virtual bool resumeRun(); + virtual bool step(); + virtual bool haltRun(); + virtual BitValue getProgramCounter(); + +private: + virtual bool internalConnect(const QString &mode); + virtual QString receivedData() const { return _rx; } + bool sendCommand(uint cmd, BitValue *res = 0, uint timeout = Port::Serial::DEFAULT_TIMEOUT); + bool readBlockCommand(uint nbBytes); + bool gotoMemory(Pic::MemoryRangeType type, uint offset); +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1.xml b/src/progs/icd1/base/icd1.xml new file mode 100644 index 0000000..4be7e3e --- /dev/null +++ b/src/progs/icd1/base/icd1.xml @@ -0,0 +1,25 @@ +<!-- ************************************************************************* --> +<!-- * 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="icd1"> + <device name="16F870" family="0x02" /> + <device name="16F871" family="0x02" /> + <device name="16F872" family="0x02" /> + <device name="16F873" family="0x01" /> + <device name="16F874" family="0x01" /> + <device name="16F876" family="0x00" /> + <device name="16F877" family="0x00" /> + + <!-- not sure about these: only with newer firmware --> + <device name="16F873A" family="0x01" /> + <device name="16F874A" family="0x01" /> + <device name="16F876A" family="0x00" /> + <device name="16F877A" family="0x00" /> +</type> diff --git a/src/progs/icd1/base/icd1_data.h b/src/progs/icd1/base/icd1_data.h new file mode 100644 index 0000000..4200578 --- /dev/null +++ b/src/progs/icd1/base/icd1_data.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * 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 ICD1_DATA_H +#define ICD1_DATA_H + +#include <qstring.h> + +namespace Icd1 +{ + struct Data { + uchar part; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1_prog.cpp b/src/progs/icd1/base/icd1_prog.cpp new file mode 100644 index 0000000..13d0d4c --- /dev/null +++ b/src/progs/icd1/base/icd1_prog.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * 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 "icd1_prog.h" + +#include <qdir.h> + +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" +#include "icd1_serial.h" + +//----------------------------------------------------------------------------- +void Icd1::ProgrammerBase::clear() +{ + Icd::ProgrammerBase::clear(); + _selfTestResult = ::Programmer::Nb_ResultTypes; +} + +bool Icd1::ProgrammerBase::selfTest(bool ask) +{ + log(Log::DebugLevel::Normal, " Self-test"); + _selfTestResult = (hardware().selfTest() ? ::Programmer::Pass : ::Programmer::Fail); + if ( _selfTestResult==::Programmer::Fail ) { + if ( ask && !askContinue(i18n("Self-test failed. Do you want to continue anyway?")) ) { + logUserAbort(); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- +Programmer::Properties Icd1::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; +} + +Programmer::Hardware *Icd1::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + return new Hardware(base, hd.port.device); +} + +Programmer::DeviceSpecific *Icd1::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new Icd::DeviceSpecific(base); +} diff --git a/src/progs/icd1/base/icd1_prog.h b/src/progs/icd1/base/icd1_prog.h new file mode 100644 index 0000000..721be49 --- /dev/null +++ b/src/progs/icd1/base/icd1_prog.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * 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 ICD1_PROG_H +#define ICD1_PROG_H + +#include "common/global/global.h" +#include "progs/icd2/base/icd_prog.h" +#include "icd1.h" +#include "progs/base/prog_group.h" + +namespace Icd1 +{ +class Hardware; + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Icd::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Icd::ProgrammerBase(group, data, "icd1_programmer_base") {} + virtual bool selfTest(bool ask); + ::Programmer::ResultType selfTestResult() const { return _selfTestResult; } + +protected: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } + virtual void clear(); + +private: + ::Programmer::ResultType _selfTestResult; +}; + +//----------------------------------------------------------------------------- +class Group : public Icd::Group +{ +public: + virtual QString name() const { return "icd1"; } + virtual QString label() const { return i18n("ICD1 Programmer"); } + virtual QString xmlName() const { return "icd1"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial ); } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1_serial.cpp b/src/progs/icd1/base/icd1_serial.cpp new file mode 100644 index 0000000..a506fdb --- /dev/null +++ b/src/progs/icd1/base/icd1_serial.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "icd1_serial.h" + +#include <qdatetime.h> +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +Icd1::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedDrain | NeedFlush, log) +{} + +bool Icd1::SerialPort::open() +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | IgnoreControlLines | EnableReceiver, S57600, 0); +} + +bool Icd1::SerialPort::reset() +{ + // reset + setPinOn(RTS, false, Port::PositiveLogic); + setPinOn(DTR, false, Port::PositiveLogic); + Port::msleep(10); + // remove reset + setPinOn(RTS, true, Port::PositiveLogic); + setPinOn(DTR, true, Port::PositiveLogic); + Port::msleep(10); + return true; +} + +bool Icd1::SerialPort::synchronize() +{ + if ( !setPinOn(RTS, false, Port::PositiveLogic) ) return false; + QTime time; + time.start(); + for (;;) { + bool bit; + if ( !readPin(CTS, Port::PositiveLogic, bit) ) return false; + if ( !bit) break; + if ( uint(time.elapsed())>3000 ) { // 3 seconds + log(Log::LineType::Error, i18n("Timeout synchronizing.")); + return false; + } + } + return setPinOn(RTS, true, Port::PositiveLogic); +} + +bool Icd1::SerialPort::sendCommand(uint cmd) +{ + Q_ASSERT( cmd<=0xFFFF ); + synchronize(); + char c[7] = "$XXXX\r"; + QString cs = toHex(cmd, 4); + log(Log::DebugLevel::Extra, QString("Send command: %1").arg(toPrintable(cs, PrintAlphaNum))); + c[1] = cs[0].latin1(); + c[2] = cs[1].latin1(); + c[3] = cs[2].latin1(); + c[4] = cs[3].latin1(); + return send(c, 7); +} + +bool Icd1::SerialPort::receiveByte(char &byte, bool synchronizeBefore, uint timeout) +{ + if ( synchronizeBefore && !synchronize() ) return false; + return receiveChar(byte, timeout); +} diff --git a/src/progs/icd1/base/icd1_serial.h b/src/progs/icd1/base/icd1_serial.h new file mode 100644 index 0000000..e8d03da --- /dev/null +++ b/src/progs/icd1/base/icd1_serial.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 ICD1_SERIAL_H +#define ICD1_SERIAL_H + +#include "common/port/serial.h" + +namespace Icd1 +{ + +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(); + bool reset(); + bool synchronize(); + bool sendCommand(uint cmd); + bool receiveByte(char &byte, bool synchronizeBefore, uint timeout = DEFAULT_TIMEOUT); +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/gui/Makefile.am b/src/progs/icd1/gui/Makefile.am new file mode 100644 index 0000000..183aab9 --- /dev/null +++ b/src/progs/icd1/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd1ui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libicd1ui.la + +libicd1ui_la_SOURCES = icd1_group_ui.cpp diff --git a/src/progs/icd1/gui/icd1_group_ui.cpp b/src/progs/icd1/gui/icd1_group_ui.cpp new file mode 100644 index 0000000..34f28d5 --- /dev/null +++ b/src/progs/icd1/gui/icd1_group_ui.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * 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 "icd1_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/icd1/base/icd1_prog.h" + +//---------------------------------------------------------------------------- +Icd1::AdvancedDialog::AdvancedDialog(ProgrammerBase &base, QWidget *parent) + : ::Programmer::PicAdvancedDialog(base, parent, "icd1_advanced_dialog") +{ + uint row = _selfTestContainer->numRows(); + QLabel *label = new QLabel(i18n("Result:"), _selfTestContainer); + _selfTestContainer->addWidget(label, row,row, 0,0); + _selfTestLabel = new QLabel(_selfTestContainer); + _selfTestContainer->addWidget(_selfTestLabel, row,row, 1,1); +} + +void Icd1::AdvancedDialog::updateDisplay() +{ + ::Programmer::PicAdvancedDialog::updateDisplay(); + _selfTestLabel->setText(i18n(::Programmer::RESULT_TYPE_LABELS[base().selfTestResult()])); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Icd1::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Icd1::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new AdvancedDialog(static_cast<ProgrammerBase &>(base), parent); +} diff --git a/src/progs/icd1/gui/icd1_group_ui.h b/src/progs/icd1/gui/icd1_group_ui.h new file mode 100644 index 0000000..f60562a --- /dev/null +++ b/src/progs/icd1/gui/icd1_group_ui.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * 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 ICD1_GROUP_UI_H +#define ICD1_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/icd1/base/icd1_prog.h" + +namespace Icd1 +{ +class Group; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(ProgrammerBase &base, QWidget *parent); + virtual void updateDisplay(); + +private: + QLabel *_selfTestLabel; + ProgrammerBase &base() { return static_cast<ProgrammerBase &>(_base); } +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/icd1.pro b/src/progs/icd1/icd1.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/icd1/icd1.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/icd1/xml/Makefile.am b/src/progs/icd1/xml/Makefile.am new file mode 100644 index 0000000..dab961c --- /dev/null +++ b/src/progs/icd1/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_icd1_parser +xml_icd1_parser_SOURCES = xml_icd1_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_icd1_parser_DEPENDENCIES = $(OBJECTS) +xml_icd1_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/icd1/xml/xml.pro b/src/progs/icd1/xml/xml.pro new file mode 100644 index 0000000..ebbde6c --- /dev/null +++ b/src/progs/icd1/xml/xml.pro @@ -0,0 +1,18 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_icd1_parser +SOURCES += xml_icd1_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_icd1_parser +unix:QMAKE_CLEAN += ../base/icd1_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_icd1_parser.exe +win32:QMAKE_CLEAN += ..\base\icd1_data.cpp + diff --git a/src/progs/icd1/xml/xml_icd1_parser.cpp b/src/progs/icd1/xml/xml_icd1_parser.cpp new file mode 100644 index 0000000..e09f51c --- /dev/null +++ b/src/progs/icd1/xml/xml_icd1_parser.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "progs/icd1/base/icd1_data.h" + +//----------------------------------------------------------------------------- +namespace Icd1 +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("icd1", "Icd1") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void Icd1::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.part = fromHexLabel(element.attribute("family"), 2, &ok); + if ( !ok ) qFatal("Missing or malformed family attribute"); +} + +void Icd1::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << toHexLabel(data.part, 2); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Icd1::XmlToData) diff --git a/src/progs/icd2/Makefile.am b/src/progs/icd2/Makefile.am new file mode 100644 index 0000000..cde6042 --- /dev/null +++ b/src/progs/icd2/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = icd2_data xml base gui diff --git a/src/progs/icd2/base/Makefile.am b/src/progs/icd2/base/Makefile.am new file mode 100644 index 0000000..9350219 --- /dev/null +++ b/src/progs/icd2/base/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libicd2.la +libicd2_la_SOURCES = microchip.cpp icd2.cpp icd2_prog.cpp icd2_serial.cpp \ + icd2_usb.cpp icd2_usb_firmware.cpp icd2_data.cpp icd2_debug.cpp icd.cpp \ + icd_prog.cpp icd2_debug_specific.cpp +libicd2_la_DEPENDENCIES = icd2_data.cpp + +noinst_DATA = icd2.xml +icd2_data.cpp: ../xml/xml_icd2_parser icd2.xml + ../xml/xml_icd2_parser +CLEANFILES = icd2_data.cpp diff --git a/src/progs/icd2/base/base.pro b/src/progs/icd2/base/base.pro new file mode 100644 index 0000000..6ca2f2d --- /dev/null +++ b/src/progs/icd2/base/base.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd2 +HEADERS += microchip.h icd.h icd_prog.h icd2.h icd2_data.h \ + icd2_prog.h icd2_debug_specific.h icd2_debug.h icd2_serial.h icd2_usb.h +SOURCES += microchip.cpp icd.cpp icd_prog.cpp icd2.cpp icd2_data.cpp \ + icd2_prog.cpp icd2_debug_specific.cpp icd2_debug.cpp icd2_serial.cpp icd2_usb.cpp icd2_usb_firmware.cpp diff --git a/src/progs/icd2/base/icd.cpp b/src/progs/icd2/base/icd.cpp new file mode 100644 index 0000000..bfb1129 --- /dev/null +++ b/src/progs/icd2/base/icd.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "icd.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" + +//----------------------------------------------------------------------------- +bool Icd::DeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + if ( vdata==0 ) return hardware().readMemory(type, 0, data, vdata); + bool only = ( vdata->actions & ::Programmer::OnlyProgrammedVerify ); + const Device::Array tmp = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type); + uint wordOffset; + Device::Array pdata = prepareRange(type, tmp, !only, wordOffset); + return hardware().readMemory(type, wordOffset, pdata, vdata); +} + +Device::Array Icd::DeviceSpecific::prepareRange(Pic::MemoryRangeType type, const Device::Array &data, + bool force, uint &wordOffset) +{ + if ( type!=Pic::MemoryRangeType::Code ) { + wordOffset = 0; + return data; + } + wordOffset = (force ? 0 : findNonMaskStart(type, data)); + uint nbWords = 0; + if ( wordOffset!=data.count() ) { + uint end = (force ? data.count() : findNonMaskEnd(type, data)); + nbWords = end - wordOffset + 1; + log(Log::DebugLevel::Normal, QString(" start=%1 nbWords=%2 total=%3 force=%4") + .arg(toHexLabel(wordOffset, device().nbCharsAddress())).arg(toHexLabel(nbWords, device().nbCharsAddress())) + .arg(toHexLabel(data.count(), device().nbCharsAddress())).arg(force ? "true" : "false")); + } + _base.progressMonitor().addTaskProgress(data.count()-nbWords); + return data.mid(wordOffset, nbWords); +} + +bool Icd::DeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + + uint nb = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code); + if ( device().architecture()==Pic::Architecture::P18J && type==Pic::MemoryRangeType::Config ) { + Q_ASSERT( data.count()%2==0 ); + int delta = nb - data.count()/2; // config memory words contains 1 byte + Q_ASSERT( delta>=0 ); + Device::Array rdata(delta); + uint wordOffset = device().nbWords(Pic::MemoryRangeType::Code) - delta; + if ( !hardware().readMemory(Pic::MemoryRangeType::Code, wordOffset, rdata, 0) ) return false; + Device::Array pdata(nb); + for (uint i=0; i<uint(delta); i++) pdata[i] = rdata[i]; + for (uint i=delta; i<nb; i++) { + pdata[i] = data[2*(i-delta)]; + pdata[i] |= data[2*(i-delta)+1] << 8; + } + return hardware().writeMemory(Pic::MemoryRangeType::Code, wordOffset, pdata); + } + + uint wordOffset; + Device::Array pdata = prepareRange(type, data, force, wordOffset); + if ( device().architecture()==Pic::Architecture::P18J && type==Pic::MemoryRangeType::Code ) { + uint end = wordOffset + pdata.size(); + if ( end>=device().nbWords(Pic::MemoryRangeType::Code) ) { + Device::Array rdata(device().nbWords(Pic::MemoryRangeType::Config)); + if ( !hardware().readMemory(Pic::MemoryRangeType::Code, device().nbWords(Pic::MemoryRangeType::Code), rdata, 0) ) return false; + uint n = rdata.count() / 2; + for (uint i=0; i<n; i++) { + pdata[pdata.size() - n + i] = rdata[2*i]; + pdata[pdata.size() - n + i] |= rdata[2*i+1] << 8; + } + } + } + return hardware().writeMemory(type, wordOffset, pdata); +} + +bool Icd::DeviceSpecific::doErase(bool) +{ + if ( device().architecture()==Pic::Architecture::P18J ) { // ### also true for others ? + Device::Array data(device().nbWords(Pic::MemoryRangeType::Config)); + for (uint i=0; i<data.size(); i++) data[i] = device().config()._words[i].wmask; + if ( !doWrite(Pic::MemoryRangeType::Config, data, true) ) return false; + } + return hardware().eraseAll(); +} diff --git a/src/progs/icd2/base/icd.h b/src/progs/icd2/base/icd.h new file mode 100644 index 0000000..9a65755 --- /dev/null +++ b/src/progs/icd2/base/icd.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 ICD_H +#define ICD_H + +#include "microchip.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/pic/pic/pic_memory.h" + +namespace Icd +{ +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : ::Programmer::PicHardware(base, port, QString::null) {} +// initialization + virtual bool uploadFirmware(const Pic::Memory &memory) = 0; + virtual bool setTarget() = 0; + +// status + virtual bool getFirmwareVersion(VersionData &version) = 0; + virtual bool setTargetPowerOn(bool) { return true; } + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata) = 0; + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) = 0; + virtual bool eraseAll() = 0; + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes) = 0; + virtual bool writeRegister(Address address, BitValue value, uint nbBytes) = 0; + virtual bool resumeRun() = 0; + virtual bool step() = 0; + virtual bool haltRun() = 0; + virtual BitValue getProgramCounter() = 0; + +protected: + QString _rx; + virtual bool internalConnect(const QString &mode) = 0; + virtual QString receivedData() const = 0; + virtual bool internalConnectHardware() { return internalConnect("U"); } +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool on) { return hardware().setTargetPowerOn(on); } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + Device::Array prepareRange(Pic::MemoryRangeType type, const Device::Array &data, bool force, uint &wordOffset); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2.cpp b/src/progs/icd2/base/icd2.cpp new file mode 100644 index 0000000..375fc60 --- /dev/null +++ b/src/progs/icd2/base/icd2.cpp @@ -0,0 +1,517 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "icd2.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" +#include "icd2_data.h" +#include "icd2_usb.h" + +//----------------------------------------------------------------------------- +const uchar Icd2::TARGET_MODE_VALUES[Pic::Nb_TargetModes] = { + 0x00, // stopped + 0x01, // running + 0x02 // in programming +}; + +const char * const Icd2::RESET_MODE_VALUES[Pic::Nb_ResetModes] = { + "00", // reset held + "01" // reset released +}; + +//----------------------------------------------------------------------------- +const Icd2::Hardware::VoltageTypeData Icd2::Hardware::VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes] = { + { "37", 0.07988 }, // icd Vpp + { "34", 0.03908 }, // target Vdd + { "35", 0.07988 }, // target Vpp +}; + +const char * const Icd2::Hardware::WRITE_MODE_VALUES[Pic::Nb_WriteModes] = { + "00", // write only + "01" // erase then write +}; + +const int Icd2::TestData::RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1] = { + 0x00, // pass + 0x01, // low + 0x80, // high + -2, // not used + -1 +}; + +const char * const Icd2::TestData::VOLTAGE_LABELS[Nb_VoltageTypes] = { + I18N_NOOP("Target Vdd"), I18N_NOOP("Module Vpp"), I18N_NOOP("MCLR ground"), + I18N_NOOP("MCLR Vdd"), I18N_NOOP("MCLR Vpp") +}; + +Icd2::TestData::TestData() +{ + for (uint k=0; k<Nb_VoltageTypes; k++) _voltages[k] = -1; +} + +Icd2::TestData::TestData(const QString &rx) +{ + for (uint k=0; k<Nb_VoltageTypes; k++) + _voltages[k] = fromHex(rx.mid(5 + 2*k, 2), 0); +} + +bool Icd2::TestData::pass() const +{ + for (uint k=0; k<Nb_VoltageTypes; k++) + if ( _voltages[k]!=RESULT_TYPE_VALUES[::Programmer::Pass] ) return false; + return true; +} + +QString Icd2::TestData::result(VoltageType type) const +{ + for (uint i=0; i<=(::Programmer::Nb_ResultTypes); i++) + if ( _voltages[type]==RESULT_TYPE_VALUES[i] ) return i18n(::Programmer::RESULT_TYPE_LABELS[i]); + return toHex(_voltages[type], 2); +} + +QString Icd2::TestData::pretty(VoltageType type) const +{ + return i18n(VOLTAGE_LABELS[type]) + "=" + result(type); +} + +//----------------------------------------------------------------------------- +const char *Icd2::Hardware::readCommand(Pic::MemoryRangeType type) const +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return "47"; + case Pic::MemoryRangeType::Eeprom: return "48"; + case Pic::MemoryRangeType::Config: + if ( device().architecture()==Pic::Architecture::P18J ) return "47"; + return "49"; + case Pic::MemoryRangeType::UserId: return "4A"; + case Pic::MemoryRangeType::DeviceId: + if ( device().architecture()==Pic::Architecture::P30F ) return "49"; + return "4A"; + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + if ( device().architecture()==Pic::Architecture::P16X ) return "49"; // ? + return "47"; // for baseline only ? + case Pic::MemoryRangeType::DebugVector: return "40"; + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +const char *Icd2::Hardware::writeCommand(Pic::MemoryRangeType type) const +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return "43"; + case Pic::MemoryRangeType::Eeprom: return "44"; + case Pic::MemoryRangeType::Config: + if ( device().architecture()==Pic::Architecture::P18J ) return "43"; + return "45"; + case Pic::MemoryRangeType::UserId: return "46"; + case Pic::MemoryRangeType::DeviceId: break; + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + if ( device().architecture()==Pic::Architecture::P16X ) return "45"; // ? + return "43"; // for baseline only ? + case Pic::MemoryRangeType::DebugVector: return "41"; + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +bool Icd2::Hardware::uploadFirmware(const Pic::Memory &memory) +{ + if ( !internalConnect("V") ) return false; + log(Log::LineType::Information, " Uploading firmware to ICD2..."); + uint start = 0x0004, size = 0x1BFB; + QString cmd = "10" + toHex(start, 4) + toHex(size, 4); + if ( !command(cmd, 0) ) return false; + uint nbBytesWord = memory.device().nbBytesWord(Pic::MemoryRangeType::Code); // should be 2 for 16F876 + Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Code); + if ( !writeBlock(nbBytesWord, data, start, size) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + if ( !internalConnect("U") ) return false; + return true; +} + +bool Icd2::Hardware::setTarget() +{ + log(Log::DebugLevel::Normal, " Set target"); + // set target family + const Icd2::Data &d = data(device().name()); + if ( !command(QString("2A") + toHex(d.famid, 2), 0) ) return false; + // set code range end + Address end = device().range(Pic::MemoryRangeType::Code).end; + if ( device().range(Pic::MemoryRangeType::Cal).start==end ) end += 1; + if ( !command("06" + toHex(end, 6), 0) ) return false; + return true; +} + +bool Icd2::Hardware::setup() +{ + // ?? + if ( device().architecture()==Pic::Architecture::P30F ) + if ( !command("0900", 0) ) return false; + + // ?? + _port->send("$7F00\x0D", 6); + QString s; + if ( !_port->receive(2, s) ) return false; + if ( s!="02" ) { + log(Log::LineType::Error, i18n("Unexpected answer ($7F00) from ICD2 (%1).").arg(s)); + return false; + } + + // ?? + if ( !command("08", 2) ) return false; + if ( _rx.mid(5, 2)!="00" ) { + log(Log::LineType::Error, i18n("Unexpected answer (08) from ICD2 (%1).").arg(_rx)); + return false; + } + + return !hasError(); +} + +bool Icd2::Hardware::sendCommand(const QString &s) +{ + //format: <LLXX....CC> + QString cs = s.upper(); + QString tx = "<"; + tx += toHex(cs.length() + 6, 2); + tx += cs; + uchar chk = tx[1].latin1() + tx[2].latin1(); + for (uint i=0; i<uint(s.length()); i++) chk += cs[i].latin1(); + tx += toHex(chk, 2); + tx += '>'; + log(Log::DebugLevel::Extra, QString("send command: '%1'").arg(tx)); + QByteArray a = toAscii(tx); + return _port->send(a.data(), a.count()); +} + +bool Icd2::Hardware::receiveResponse(const QString &command, uint responseSize, bool poll) +{ + // format: [LLXX...CC] + uint size = responseSize + 8; + if ( poll && _port->type()==PortType::USB ) { + if ( !static_cast<USBPort *>(_port)->poll(size, _rx) ) return false; + } else if ( !_port->receive(size, _rx, 180000) ) return false; // is 3 minutes enough ?? (we should really have an abort button here...) + log(Log::DebugLevel::Extra, QString("received answer: '%1'").arg(_rx)); + if ( size!=fromHex(_rx.mid(1, 2), 0) ) { + log(Log::LineType::Error, i18n("Received length too short.")); + return false; + } + if ( uint(_rx.length())!=size ) { + log(Log::LineType::Error, i18n("Received string too short.")); + return false; + } + if ( _rx[0]!='[' || _rx[size-1]!=']' ) { + log(Log::LineType::Error, i18n("Malformed string received \"%1\"").arg(_rx)); + return false; + } + if ( command.mid(0, 2)!=_rx.mid(3, 2) ) { + log(Log::LineType::Error, i18n("Wrong return value (\"%1\"; was expecting \"%2\")") + .arg(_rx.mid(3, 2)).arg(command.mid(0, 2))); + return false; + } + // verify the checksum + uchar chk = 0; + for (uint i=1; i<size-3; i++) chk += _rx[i].latin1(); + if ( chk!=fromHex(_rx.mid(size-3, 2), 0) ) { + log(Log::LineType::Error, i18n("Bad checksum for received string")); + return false; + } + return true; +} + +bool Icd2::Hardware::command(const QString &command, uint responseSize) +{ + if ( hasError() ) return false; + if ( !sendCommand(command) ) return false; + if ( !receiveResponse(command, responseSize, false) ) return false; + return true; +} + +bool Icd2::Hardware::getFirmwareVersion(VersionData &version) +{ + if ( !command("01", 6) ) return false; + version = VersionData::fromHexString(_rx.mid(5, 6)); + return true; +} + +uint Icd2::Hardware::getFirmwareId() +{ + if ( !command("07", 2) ) return 0; + return fromHex(_rx.mid(5, 2), 0); +} + +bool Icd2::Hardware::getDebugExecVersion(VersionData &version) +{ + if ( !command("04", 6) ) return false; + version = VersionData::fromHexString(_rx.mid(5, 6)); + return true; +} + +bool Icd2::Hardware::setTargetPowerOn(bool on) +{ + return command(QString("05") + (on ? "FF" : "00"), 0); +} + +bool Icd2::Hardware::readVoltage(Pic::VoltageType type, double &value) +{ + if ( !command(VOLTAGE_TYPE_DATA[type].command, 2) ) return false; + value = VOLTAGE_TYPE_DATA[type].factor * fromHex(_rx.mid(5, 2), 0); + return true; +} + +bool Icd2::Hardware::readVoltages(VoltagesData &voltages) +{ + for (uint i=0; i<Pic::Nb_VoltageTypes; i++) { + if ( !readVoltage(Pic::VoltageType(i), voltages[i].value) ) return false; + voltages[i].error = false; + } + return true; +} + +bool Icd2::Hardware::getTargetMode(Pic::TargetMode &tmode) +{ + if ( !command("2C", 2) ) return false; + uchar mode = fromHex(_rx.mid(5, 2), 0); + for (uint i=0; i<Pic::Nb_TargetModes; i++) { + if ( mode!=TARGET_MODE_VALUES[i] ) continue; + tmode = Pic::TargetMode(i); + return true; + } + Q_ASSERT(false); + return false; +} + +bool Icd2::Hardware::setTargetReset(Pic::ResetMode mode) +{ + return command(QString("33") + RESET_MODE_VALUES[mode], 0); +} + +bool Icd2::Hardware::selfTest(TestData &test) +{ + if ( !command("02", 10) ) return false; + test = TestData(_rx); + return true; +} + +bool Icd2::Hardware::readBlock(uint nbBytesWord, uint nbWords, Device::Array &data) +{ + //qDebug("readBlock %i %s", nbBytesWord, toHex(nbWords, 8).data()); + // receive data + uint length = 2*nbBytesWord*nbWords+4; + QString s; + uint i = 0; + while ( i<length ) { + uint maxSize = (_port->type()==PortType::Serial ? 2*nbBytesWord : 0x100); + uint size = QMIN(maxSize, length-i); + QString tmp; + if ( _port->type()==PortType::USB ) { + if ( !static_cast<USBPort *>(_port)->dataReceive(size, tmp) ) return false; + } else if ( !_port->receive(size, tmp) ) return false; + s += tmp; + i += size; + } + + // treat data + if ( s[0]!='{' || s[s.length()-1]!='}' ) { + log(Log::LineType::Error, i18n("Invalid begin or end character for read block.")); + return false; + } + log(Log::DebugLevel::Max, "received: " + s); + data.resize(nbWords); + Q_UINT8 chk = 0; + for (uint i=0; i<nbWords; i++) { + QString ts = s.mid(1+2*nbBytesWord*i, 2*nbBytesWord); + //if ( i<10 ) qDebug("%i: %s", i, ts.data()); + data[i] = 0; + for (int k=nbBytesWord-1; k>=0; k--) { + data[i] = data[i] << 8; + data[i] |= fromHex(ts.mid(2*k, 2), 0); + chk += ts[2*k].latin1() + ts[2*k+1].latin1(); + } + } + + QString cs = s.mid(s.length()-3, 2); + if ( chk!=fromHex(cs, 0) ) { + log(Log::LineType::Error, i18n("Bad checksum for read block: %1 (%2 expected).").arg(cs).arg(toHex(chk, 2))); + return false; + } + return true; +} + +bool Icd2::Hardware::readMemory(Pic::MemoryRangeType type, uint wordOffset, + Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + const char *r = readCommand(type); + if ( r==0 ) return false; + uint nbBytesWord = device().nbBytesWord(type); + uint div = 2; + if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1; + uint inc = device().addressIncrement(type); + Address start = device().range(type).start; // address + uint todo = inc * data.count(); // address + uint offset = inc * wordOffset; // address + //qDebug("read size=%s div=%i nbBytes=%i", toHex(size, 8).data(), div, nbBytesWord); + data.resize(0); + do { + uint size = QMIN(todo, uint(0x1000)); // addresses + uint nb = size / inc; // word + //qDebug("read %s start=%s size=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data()); + QString cmd = r + toHex(start+offset, 8) + toHex(nb/div, 8); + if ( !command(cmd, 0) ) return false; + Device::Array pdata; + if ( !readBlock(nbBytesWord, nb, pdata) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + if (vdata) { + for (uint i=0; i<pdata.count(); i++) + if ( !verifyWord(wordOffset+data.count()+i, pdata[i], type, *vdata) ) return false; + } + data += pdata; + offset += size; + todo -= size; + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(nb); + } while ( todo!=0 ); + return true; +} + +bool Icd2::Hardware::writeBlock(uint nbBytesWord, const Device::Array &data, uint wordIndex, uint nbWords) +{ + log(Log::DebugLevel::Extra, QString("writeBlock offset:%1 nbWords:%2 (size: %3)").arg(toHex(wordIndex, 8)).arg(toHex(nbWords, 8)).arg(toHex(data.size(), 8))); + Q_ASSERT( wordIndex+nbWords<=data.size() ); + // prepare data + QString s = "{"; + uchar chk = 0; + for (uint i=0; i<nbWords; i++) { + QString ts = toHex(data[wordIndex+i], 2*nbBytesWord); + for (int k=nbBytesWord-1; k>=0; k--) { + //if ( i<10 || i>=nbWords-10 ) qDebug("send: %i-%i %s", i, k, ts.mid(2*k, 2).data()); + s += ts.mid(2*k, 2); + chk += ts[2*k].latin1() + ts[2*k+1].latin1(); + } + } + s += toHex(chk, 2); + s += "}"; + log(Log::DebugLevel::Max, "send: " + s); + + // send data + uint i = 0; + while ( i<uint(s.length()) ) { + uint maxSize = (_port->description().type==PortType::Serial ? 2*nbBytesWord : 0x100); + if ( _port->description().type==PortType::Serial && i==0 ) maxSize = 1; + uint size = QMIN(maxSize, s.length()-i); + QByteArray a = toAscii(s); + if ( _port->type()==PortType::USB ) { + if ( !static_cast<USBPort *>(_port)->dataSend(a.data()+i, size) ) return false; + } else if ( !_port->send(a.data()+i, size) ) return false; + i += size; + } + + //qDebug("done sending %i words (chk=%s)", nbWords, toHex(chk, 2).data()); + return true; +} + +bool Icd2::Hardware::writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) +{ + //qDebug("write memory: offset:%s nbWords:%s (size: %s)", toHex(wordOffset, 4).data(), toHex(nbWords, 4).data(), toHex(data.size(), 4).data()); + const char *w = writeCommand(type); + if ( w==0 ) return true; + uint nbBytesWord = device().nbBytesWord(type); + uint div = 2; + if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1; + uint inc = device().addressIncrement(type); + Address start = device().range(type).start; // address + uint todo = inc * data.count(); // address + uint offset = inc * wordOffset; // address + uint index = 0; + //qDebug("write todo=%s div=%i nbBytes=%i dataSize=%i", toHex(todo, 8).data(), div, nbBytesWord, data.size()); + do { + uint size = QMIN(todo, uint(0x1000)); // address + uint nb = size / inc; // word + //qDebug("write %s start=%s nbWords=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data()); + QString cmd = w + toHex(start+offset+index, 8) + toHex(nb/div, 8); + if ( !command(cmd, 0) ) return false; + if ( !writeBlock(nbBytesWord, data, index/inc, nb) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + index += size; + todo -= size; + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(nb); + } while ( todo!=0 ); + return true; +} + +bool Icd2::Hardware::eraseAll() +{ + setTargetReset(Pic::ResetHeld); + if ( hasError() ) return false; + if ( !sendCommand("29") ) return false; + if ( !receiveResponse("29", 0, true) ) return false; // poll + return true; +} + +bool Icd2::Hardware::haltRun() +{ + return command("2E", 0); +} + +bool Icd2::Hardware::step() +{ + return command("2F", 0); +} + +bool Icd2::Hardware::resumeRun() +{ + return command("30", 0); +} + +bool Icd2::Hardware::setWriteMode(Pic::WriteMode mode) +{ + return command(QString("4B") + WRITE_MODE_VALUES[mode], 0); +} + +bool Icd2::Hardware::writeRegister(Address address, BitValue value, uint nbBytes) +{ + QString cmd = "1B" + toHex(address, 8) + toHex(nbBytes, 8); + if ( !command(cmd, 0) ) return false; + Device::Array data(nbBytes); + for (uint i=0; i<nbBytes; i++) data[nbBytes-i-1] = value.byte(i); + if ( !writeBlock(1, data, 0, nbBytes) ) return false; + return receiveResponse(cmd, 0, false); +} + +bool Icd2::Hardware::readRegister(Address address, BitValue &value, uint nbBytes) +{ + QString cmd = "1E" + toHex(address, 8) + toHex(nbBytes, 8); + if ( !command(cmd, 0) ) return false; + Device::Array data; + if ( !readBlock(1, nbBytes, data) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + value = 0; + for (uint i=0; i<nbBytes; i++) { + value <<= 8; + value += data[i]; + } + return true; +} + +BitValue Icd2::Hardware::getProgramCounter() +{ + if ( !command("3D", 8) ) return 0; + return fromHex(_rx.mid(5, 8), 0); +} diff --git a/src/progs/icd2/base/icd2.h b/src/progs/icd2/base/icd2.h new file mode 100644 index 0000000..1c9c1b9 --- /dev/null +++ b/src/progs/icd2/base/icd2.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 ICD2_H +#define ICD2_H + +#include "icd.h" + +namespace Icd2 +{ +//----------------------------------------------------------------------------- + extern const uchar TARGET_MODE_VALUES[Pic::Nb_TargetModes]; + extern const char * const RESET_MODE_VALUES[Pic::Nb_ResetModes]; + + class TestData { + public: + TestData(); + TestData(const QString &rx); + enum VoltageType { TargetVdd = 0, ModuleVpp, MclrGround, MclrVdd, MclrVpp, + Nb_VoltageTypes }; + bool pass() const; + QString result(VoltageType type) const; + QString pretty(VoltageType type) const; + static const char * const VOLTAGE_LABELS[Nb_VoltageTypes]; + + private: + int _voltages[Nb_VoltageTypes]; + static const int RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1]; + }; + +//----------------------------------------------------------------------------- +class Hardware : public Icd::Hardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : Icd::Hardware(base, port) {} + bool command(const QString &command, uint responseSize); + +// initialization + virtual bool uploadFirmware(const Pic::Memory &memory); + virtual bool setTarget(); + bool setup(); + +// status + virtual bool getFirmwareVersion(VersionData &version); + uint getFirmwareId(); + bool getDebugExecVersion(VersionData &version); + virtual bool setTargetPowerOn(bool on); + virtual bool readVoltage(Pic::VoltageType type, double &value); + virtual bool readVoltages(VoltagesData &voltages); + virtual bool getTargetMode(Pic::TargetMode &mode); + virtual bool setTargetReset(Pic::ResetMode mode); + bool selfTest(TestData &test); + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data); + virtual bool eraseAll(); + bool setWriteMode(Pic::WriteMode mode); + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes); + virtual bool writeRegister(Address address, BitValue value, uint nbBytes); + virtual bool resumeRun(); + virtual bool step(); + virtual bool haltRun(); + virtual BitValue getProgramCounter(); + +protected: + virtual QString receivedData() const { return _rx.mid(5, _rx.length()-8); } + +private: + struct VoltageTypeData { + const char *command; + double factor; + }; + static const VoltageTypeData VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes]; + static const char * const WRITE_MODE_VALUES[Pic::Nb_WriteModes]; + + bool sendCommand(const QString &command); + bool receiveResponse(const QString &command, uint responseSize, bool poll); + bool readBlock(uint nbBytesWord, uint nbWords, Device::Array &data); + bool writeBlock(uint nbBytesWord, const Device::Array &data, uint wordOffset, uint nbWords); + const char *readCommand(Pic::MemoryRangeType type) const; + const char *writeCommand(Pic::MemoryRangeType type) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2.xml b/src/progs/icd2/base/icd2.xml new file mode 100644 index 0000000..3c714b2 --- /dev/null +++ b/src/progs/icd2/base/icd2.xml @@ -0,0 +1,214 @@ +<!-- ************************************************************************* --> +<!-- * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * --> +<!-- * * --> +<!-- * it under the terms of the GNU General Public License as published by * --> +<!-- * This program is free software; you can redistribute it and/or modify * --> +<!-- * the Free Software Foundation; either version 2 of the License, or * --> +<!-- * (at your option) any later version. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="icd2"> + <device name="10F200" famid="0x12" family="10F2XX" support_type="tested" /> + <device name="10F202" famid="0x12" family="10F2XX" support_type="tested" /> + <device name="10F204" famid="0x12" family="10F2XX" support_type="tested" /> + <device name="10F206" famid="0x12" family="10F2XX" support_type="tested" /> + <device name="10F220" famid="0x12" family="10F2XX" /> + <device name="10F222" famid="0x12" family="10F2XX" /> + + <device name="12F508" famid="0x11" family="16F5X" support_type="tested" /> + <device name="12F509" famid="0x11" family="16F5X" support_type="tested" /> + <device name="12F510" famid="0x11" family="16F5X" support_type="tested" /> + <device name="12F629" famid="0x05" family="12F629" support_type="tested" /> + <device name="12F635" famid="0x0C" family="12F635" support_type="tested" /> + <device name="12F675" famid="0x05" family="12F629" support_type="tested" /> + <device name="12F683" famid="0x0C" family="12F635" support_type="tested" /> + + <device name="16F505" famid="0x10" family="16F5X" /> + <device name="16F506" famid="0x12" family="16F5X" /> + <device name="16F54" famid="0x0E" family="16F5X" support_type="tested" /> + <device name="16F57" famid="0x0F" family="16F5X" support_type="tested" /> + <device name="16F59" famid="0x0F" family="16F5X" support_type="tested" /> + <device name="16F616" famid="0x1A" family="16F61X" /> + <device name="16F627" famid="0x19" family="16F72" /> + <device name="16F628" famid="0x19" family="16F72" /> + <device name="16F627A" famid="0x09" family="16F648A" support_type="tested" /> + <device name="16F628A" famid="0x09" family="16F648A" support_type="tested" /> + <device name="16F630" famid="0x05" family="16F676" /> + <device name="16F631" famid="0x0C" family="12F635" /> + <device name="16F636" famid="0x0C" family="12F635" /> + <device name="16F639" famid="0x0C" family="12F635" /> + <device name="16F648A" famid="0x09" family="16F648A" support_type="tested" /> + <device name="16F676" famid="0x05" family="16F676" /> + <device name="16F677" famid="0x0C" family="16F677" /> + <device name="16F684" famid="0x0C" family="16F684" support_type="tested" /> + <device name="16F685" famid="0x0C" family="16F688" support_type="tested" /> + <device name="16F687" famid="0x0C" family="16F688" support_type="tested" /> + <device name="16F688" famid="0x0C" family="16F688" support_type="tested" /> + <device name="16F689" famid="0x0C" family="16F688" support_type="tested" /> + <device name="16F690" famid="0x0C" family="16F688" support_type="tested" /> + <device name="16F716" famid="0x0B" family="16F716" /> + <device name="16F72" famid="0x21" family="16F72" /> + <device name="16F73" famid="0x0A" family="16F7X" /> + <device name="16F74" famid="0x0A" family="16F7X" /> + <device name="16F76" famid="0x0A" family="16F7X" /> + <device name="16F77" famid="0x0A" family="16F7X" /> + <device name="16F737" famid="0x0A" family="16F7X7" support_type="tested" /> + <device name="16F747" famid="0x0A" family="16F7X7" support_type="tested" /> + <device name="16F767" famid="0x0A" family="16F7X7" support_type="tested" /> + <device name="16F777" famid="0x0A" family="16F7X7" support_type="tested" /> + <device name="16F785" famid="0x15" family="16F785" /> + <device name="16F818" famid="0x06" family="16F819" support_type="tested" /> + <device name="16F819" famid="0x06" family="16F819" support_type="tested" /> + <device name="16F84A" famid="0x20" family="16F72" /> + <device name="16F87" famid="0x08" family="16F88" support_type="tested" /> + <device name="16F870" famid="0x03" family="16F872" /> + <device name="16F871" famid="0x03" family="16F872" support_type="tested" debug_support_type="tested" /> + <device name="16F872" famid="0x03" family="16F872" support_type="tested" /> + <device name="16F873" famid="0x03" family="16F874" support_type="tested" /> + <device name="16F873A" famid="0x04" family="16F874" /> + <device name="16F874" famid="0x03" family="16F874" support_type="tested" /> + <device name="16F874A" famid="0x04" family="16F874" /> + <device name="16F876" famid="0x03" family="16F877" support_type="tested" /> + <device name="16F876A" famid="0x04" family="16F877" /> + <device name="16F877" famid="0x03" family="16F877" support_type="tested" debug_support_type="tested" /> + <device name="16F877A" famid="0x04" family="16F877" /> + <device name="16F88" famid="0x08" family="16F88" support_type="tested" /> + <device name="16F913" famid="0x14" family="16F916" /> + <device name="16F914" famid="0x14" family="16F916" /> + <device name="16F916" famid="0x14" family="16F916" /> + <device name="16F917" famid="0x14" family="16F916" /> + <device name="16F946" famid="0x14" family="16F916" /> + + <device name="18C601" famid="0x81" family="18CX01" /> + <device name="18C801" famid="0x81" family="18CX01" /> + + <device name="18F242" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F248" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F252" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F258" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F442" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F448" famid="0x82" family="18F_4" support_type="tested" /> + <device name="18F452" famid="0x82" family="18F_4" support_type="tested" debug_support_type="tested" /> + <device name="18F458" famid="0x82" family="18F_4" support_type="tested" debug_support_type="tested" /> + + <device name="18F1220" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F1230" famid="0x8F" family="18F_5" /> + <device name="18F1320" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F1330" famid="0x8F" family="18F_5" /> + <device name="18F2220" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F2221" famid="0x8C" family="18F_5" /> + <device name="18F2320" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F2321" famid="0x8C" family="18F_5" /> + <device name="18F2331" famid="0x87" family="18F_4" /> + <device name="18F2410" famid="0x8C" family="18F_5" /> + <device name="18F2420" famid="0x8C" family="18F_5" /> + <device name="18F2423" famid="0x8B" family="18F_5" /> + <device name="18F2431" famid="0x87" family="18F_4" /> + <device name="18F2439" famid="0x85" family="18F_4" /> + <device name="18F2450" famid="0x8C" family="18F_5" /> + <device name="18F2455" famid="0x8B" family="18F_5" /> + <device name="18F2480" famid="0x8C" family="18F_5" support_type="tested" /> + <device name="18F2510" famid="0x88" family="18F_5" support_type="tested" /> + <device name="18F2515" famid="0x88" family="18F_5" /> + <device name="18F2520" famid="0x8C" family="18F_5" /> + <device name="18F2523" famid="0x8B" family="18F_5" /> + <device name="18F2525" famid="0x88" family="18F_5" /> + <device name="18F2539" famid="0x85" family="18F_4" /> + <device name="18F2550" famid="0x8B" family="18F_5" /> + <device name="18F2580" famid="0x8C" family="18F_5" support_type="tested" /> + <device name="18F2585" famid="0x88" family="18F_5" /> + <device name="18F2610" famid="0x88" family="18F_5" /> + <device name="18F2620" famid="0x88" family="18F_5" /> + <device name="18F2680" famid="0x88" family="18F_5" /> + <device name="18F2682" famid="0x90" family="18F_5" /> + <device name="18F2685" famid="0x90" family="18F_5" /> + + <device name="18F4220" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F4221" famid="0x8C" family="18F_5" /> + <device name="18F4320" famid="0x83" family="18F_4" support_type="tested" /> + <device name="18F4321" famid="0x8C" family="18F_5" /> + <device name="18F4331" famid="0x87" family="18F_4" /> + <device name="18F4410" famid="0x8C" family="18F_5" /> + <device name="18F4420" famid="0x8C" family="18F_5" /> + <device name="18F4423" famid="0x8B" family="18F_5" /> + <device name="18F4431" famid="0x87" family="18F_4" /> + <device name="18F4439" famid="0x85" family="18F_4" /> + <device name="18F4450" famid="0x8C" family="18F_5" /> + <device name="18F4455" famid="0x8B" family="18F_5" /> + <device name="18F4480" famid="0x8C" family="18F_5" support_type="tested" /> + <device name="18F4510" famid="0x88" family="18F_5" support_type="tested" /> + <device name="18F4515" famid="0x88" family="18F_5" /> + <device name="18F4520" famid="0x8C" family="18F_5" /> + <device name="18F4523" famid="0x8B" family="18F_5" /> + <device name="18F4525" famid="0x88" family="18F_5" /> + <device name="18F4539" famid="0x85" family="18F_4" /> + <device name="18F4550" famid="0x8B" family="18F_5" /> + <device name="18F4580" famid="0x8C" family="18F_5" support_type="tested" /> + <device name="18F4585" famid="0x88" family="18F_5" /> + <device name="18F4610" famid="0x88" family="18F_5" /> + <device name="18F4620" famid="0x88" family="18F_5" /> + <device name="18F4680" famid="0x88" family="18F_5" /> + <device name="18F4682" famid="0x90" family="18F_5" /> + <device name="18F4685" famid="0x90" family="18F_5" /> + + <device name="18F6310" famid="0x8A" family="18F_4" /> + <device name="18F6390" famid="0x8A" family="18F_4" /> + <device name="18F6410" famid="0x8A" family="18F_5" /> + <device name="18F6490" famid="0x8A" family="18F_5" /> + <device name="18F6520" famid="0x84" family="18F_4" /> + <device name="18F6525" famid="0x86" family="18F_4" /> + <device name="18F6527" famid="0x8D" family="18F_5" /> + <device name="18F6585" famid="0x86" family="18F_4" /> + <device name="18F6620" famid="0x84" family="18F_4" /> + <device name="18F6621" famid="0x86" family="18F_4" /> + <device name="18F6622" famid="0x8D" family="18F_5" /> + <device name="18F6627" famid="0x8D" family="18F_5" /> + <device name="18F6680" famid="0x86" family="18F_4" /> + <device name="18F6720" famid="0x84" family="18F_4" /> + <device name="18F6722" famid="0x8D" family="18F_5" /> + + <device name="18F8310" famid="0x8A" family="18F_4" /> + <device name="18F8390" famid="0x8A" family="18F_4" /> + <device name="18F8410" famid="0x8A" family="18F_5" /> + <device name="18F8490" famid="0x8A" family="18F_5" /> + <device name="18F8520" famid="0x84" family="18F_4" /> + <device name="18F8525" famid="0x86" family="18F_4" /> + <device name="18F8527" famid="0x8D" family="18F_5" /> + <device name="18F8585" famid="0x86" family="18F_4" /> + <device name="18F8620" famid="0x84" family="18F_4" /> + <device name="18F8621" famid="0x86" family="18F_4" /> + <device name="18F8622" famid="0x8D" family="18F_5" /> + <device name="18F8627" famid="0x8D" family="18F_5" /> + <device name="18F8680" famid="0x86" family="18F_4" /> + <device name="18F8720" famid="0x84" family="18F_4" /> + <device name="18F8722" famid="0x8D" family="18F_5" /> + + <device name="18F24J10" famid="0x40" family="18F_J" /> + <device name="18F66J60" famid="0x40" family="18F_J" support_type="tested" /> + + <device name="30F2010" famid="0xBB" family="30F" /> + <device name="30F2011" famid="0xBB" family="30F" /> + <device name="30F2012" famid="0xBB" family="30F" /> + <device name="30F3010" famid="0xBB" family="30F" /> + <device name="30F3011" famid="0xBB" family="30F" /> + <device name="30F3012" famid="0xBB" family="30F" /> + <device name="30F3013" famid="0xBB" family="30F" /> + <device name="30F3014" famid="0xBB" family="30F" /> + <device name="30F4011" famid="0xBB" family="30F" /> + <device name="30F4012" famid="0xBB" family="30F" /> + <device name="30F4013" famid="0xBB" family="30F" /> + <device name="30F5011" famid="0xBB" family="30F" /> + <device name="30F5013" famid="0xBB" family="30F" /> + <device name="30F6010" famid="0xBB" family="30F" /> + <device name="30F6011" famid="0xBB" family="30F" /> + <device name="30F6012" famid="0xBB" family="30F" /> + <device name="30F6013" famid="0xBB" family="30F" /> + <device name="30F6014" famid="0xBB" family="30F" /> + <device name="30F6015" famid="0xBB" family="30F" /> + <device name="30F6010A" famid="0xBB" family="30F" /> + <device name="30F6011A" famid="0xBB" family="30F" /> + <device name="30F6012A" famid="0xBB" family="30F" /> + <device name="30F6013A" famid="0xBB" family="30F" /> + <device name="30F6014A" famid="0xBB" family="30F" /> +</type>
\ No newline at end of file diff --git a/src/progs/icd2/base/icd2_data.h b/src/progs/icd2/base/icd2_data.h new file mode 100644 index 0000000..ceda394 --- /dev/null +++ b/src/progs/icd2/base/icd2_data.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 ICD2_DATA_H +#define ICD2_DATA_H + +#include "common/common/group.h" + +namespace Icd2 +{ + struct Version { + uchar major, minor, dot; + }; + enum { Nb_Firmwares = 15 }; + struct FirmwareVersionData { + uchar mplabMajor, mplabMinor; + Version version[Nb_Firmwares]; + }; + extern const FirmwareVersionData MIN_VERSION_DATA; + extern const FirmwareVersionData MAX_VERSION_DATA; + struct FamilyData { + const char *name; + uchar efid; + const char *debugExec; + uint debugExecOffset; // in the hex file + uint wreg, fsr, status; + }; + extern const FamilyData FAMILY_DATA[]; + struct Data { + uint famid; + ::Group::Support debugSupport; + }; + extern const Data &data(const QString &device); + extern uint family(const QString &device); +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_debug.cpp b/src/progs/icd2/base/icd2_debug.cpp new file mode 100644 index 0000000..62f6404 --- /dev/null +++ b/src/progs/icd2/base/icd2_debug.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 "icd2_debug.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/pic/base/pic_register.h" +#include "devices/pic/pic/pic_group.h" +#include "icd2_data.h" +#include "icd2_debug_specific.h" + +//----------------------------------------------------------------------------- +Icd2::DebuggerSpecific *Icd2::Debugger::specific() { return static_cast<Icd2::DebuggerSpecific *>(_specific); } + +bool Icd2::Debugger::waitForTargetMode(Pic::TargetMode mode) +{ + Pic::TargetMode rmode; + for (uint i=0; i<20; i++) { + if ( !programmer().getTargetMode(rmode) ) return false; + if ( rmode==mode ) return true; + Port::msleep(200); + } + log(Log::LineType::Error, QString("Timeout waiting for mode: %1 (target is in mode: %2).") + .arg(i18n(Pic::TARGET_MODE_LABELS[mode])).arg(i18n(Pic::TARGET_MODE_LABELS[rmode]))); + return false; +} + +bool Icd2::Debugger::init(bool last) +{ + _initLast = last; + return ::Debugger::PicBase::init(); +} + +bool Icd2::Debugger::internalInit() +{ + return specific()->init(_initLast); +} + +bool Icd2::Debugger::updateState() +{ + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + switch (mode) { + case Pic::TargetStopped: _programmer.setState(::Programmer::Halted); break; + case Pic::TargetRunning: _programmer.setState(::Programmer::Running); break; + case Pic::TargetInProgramming: _programmer.setState(::Programmer::Stopped); break; + case Pic::Nb_TargetModes: Q_ASSERT(false); break; + } + return true; +} + +bool Icd2::Debugger::setBreakpoints(const QValueList<Address> &addresses) +{ + if ( addresses.count()==0 ) return specific()->setBreakpoint(Address()); + for (uint i=0; i<uint(addresses.count()); i++) { + log(Log::DebugLevel::Normal, QString("Set breakpoint at %1").arg(toHexLabel(addresses[i], device()->nbCharsAddress()))); + if ( !specific()->setBreakpoint(addresses[i]) ) return false; + } + return true; +} + +bool Icd2::Debugger::internalRun() +{ + return hardware()->resumeRun(); +} + +bool Icd2::Debugger::hardHalt() +{ + log(Log::LineType::Warning, i18n("Failed to halt target: try a reset.")); + return reset(); +} + +bool Icd2::Debugger::softHalt(bool &success) +{ + if ( !hardware()->haltRun() ) return false; + success = waitForTargetMode(Pic::TargetStopped); + return true; +} + +bool Icd2::Debugger::internalReset() +{ + return specific()->reset(); +} + +bool Icd2::Debugger::internalStep() +{ + return hardware()->step(); +} + +bool Icd2::Debugger::readRegister(const Register::TypeData &data, BitValue &value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1); + if ( data.name()=="PC" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()); return !hasError(); } + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1); + if ( name=="PCL" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(0); return !hasError(); } + if ( name=="PCLATH" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(1); return !hasError(); } + return hardware()->readRegister(specific()->addressRegister(data.address()), value, 1); +} + +bool Icd2::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1); + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1); + return hardware()->writeRegister(specific()->addressRegister(data.address()), value, 1); +} + +//----------------------------------------------------------------------------- +Icd2::DebugProgrammer::DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data) + : Icd2::ProgrammerBase(group, data, "icd2_programmer") +{} + +void Icd2::DebugProgrammer::clear() +{ + Icd2::ProgrammerBase::clear(); + _debugExecutiveVersion.clear(); +} + +bool Icd2::DebugProgrammer::internalSetupHardware() +{ + if ( _specific==0 ) return true; + const FamilyData &fdata = FAMILY_DATA[family(device()->name())]; + + // find debug executive file + PURL::Directory dir(::Programmer::GroupConfig::firmwareDirectory(group())); + if ( !dir.exists() ) { + log(Log::LineType::Error, i18n("Firmware directory not configured.")); + return false; + } + uint reservedBank = 0; + QString filename; + if ( device()->is18Family() ) { + Debugger *debug = static_cast<Debugger *>(debugger()); + reservedBank = static_cast<const P18FDebuggerSpecific *>(debug->specific())->reservedBank(); + filename = QString("de18F_BANK%1.hex").arg(QString(toString(NumberBase::Dec, reservedBank, 2))); + } else filename = QString("de%1.hex").arg(fdata.debugExec); + PURL::Url url = dir.findMatchingFilename(filename); + log(Log::DebugLevel::Normal, QString(" Debug executive file: %1").arg(url.pretty())); + if ( !url.exists() ) { + log(Log::LineType::Error, i18n("Could not find debug executive file \"%1\".").arg(url.pretty())); + return false; + } + // upload hex file + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + QStringList errors; + HexBuffer hbuffer; + if ( !hbuffer.load(file.stream(), errors) ) { + log(Log::LineType::Error, i18n("Could not read debug executive file \"%1\": %2.").arg(url.pretty()).arg(errors[0])); + return false; + } + uint nbWords = device()->nbWords(Pic::MemoryRangeType::Code); + uint offset = nbWords - 0x100; + if ( fdata.debugExecOffset!=0 && fdata.debugExecOffset!=offset ) + for (uint i=0; i<0x100; i++) hbuffer.insert(offset+i, hbuffer[fdata.debugExecOffset+i]); + Pic::Memory::WarningTypes warningTypes; + QStringList warnings; + QMap<uint, bool> inRange; + Pic::Memory memory(*device()); + memory.fromHexBuffer(Pic::MemoryRangeType::Code, hbuffer, warningTypes, warnings, inRange); + _deArray = memory.arrayForWriting(Pic::MemoryRangeType::Code); + if ( device()->is18Family() ) { + // that's a bit ugly but it cannot be guessed for 18F2455 family... + uint size; + switch (reservedBank) { + case 0: size = 0x0E0; break; + case 12: + case 14: size = 0x140; break; + default: size = 0x120; break; + } + _deStart = nbWords - size; + _deEnd = nbWords - 1; + for (uint i=0; i<size; i++) { + BitValue v = memory.word(Pic::MemoryRangeType::Code, i); + memory.setWord(Pic::MemoryRangeType::Code, i, BitValue()); + memory.setWord(Pic::MemoryRangeType::Code, _deStart+i, v); + } + _deArray = memory.arrayForWriting(Pic::MemoryRangeType::Code); + } else { + _deStart = specific()->findNonMaskStart(Pic::MemoryRangeType::Code, _deArray); + _deEnd = specific()->findNonMaskEnd(Pic::MemoryRangeType::Code, _deArray); + } + log(Log::DebugLevel::Extra, QString("debug executive: \"%1\" %2:%3").arg(url.pretty()).arg(toHexLabel(_deStart, 4)).arg(toHexLabel(_deEnd, 4))); + return Icd2::ProgrammerBase::internalSetupHardware(); +} + +Pic::Memory Icd2::DebugProgrammer::toDebugMemory(const Pic::Memory &mem, bool withDebugExecutive) +{ + Pic::Memory memory = mem; + memory.setDebugOn(true); + if ( memory.hasWatchdogTimerOn() ) { + log(Log::LineType::Warning, i18n("Disabling watchdog timer for debugging")); + memory.setWatchdogTimerOn(false); + } + if ( memory.isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code program protection for debugging")); + memory.setProtection(false, Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); + } + if ( memory.isProtected(Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code write protection for debugging")); + memory.setProtection(false, Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code); + } + if ( memory.isProtected(Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code read protection for debugging")); + memory.setProtection(false, Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code); + } + uint address = _deStart * device()->addressIncrement(Pic::MemoryRangeType::Code); + Device::Array data = device()->gotoInstruction(address, false); + for (uint i=0; i<data.count(); i++) memory.setWord(Pic::MemoryRangeType::DebugVector, i, data[i]); + if ( device()->is18Family() ) + memory.setWord(Pic::MemoryRangeType::DebugVector, data.count(), 0xFF00); // ?? + if (withDebugExecutive) { + bool ok = true; + for (uint i=_deStart; i<=_deEnd; i++) { + if ( memory.word(Pic::MemoryRangeType::Code, i).isInitialized() ) ok = false; + memory.setWord(Pic::MemoryRangeType::Code, i, _deArray[i]); + } + if ( !ok ) log(Log::LineType::Warning, i18n("Memory area for debug executive was not empty. Overwrite it and continue anyway...")); + } + return memory; +} + +bool Icd2::DebugProgrammer::writeDebugExecutive() +{ + log(Log::LineType::Information, i18n(" Write debug executive")); + Device::Array data = _deArray.mid(_deStart, _deEnd - _deStart + 1); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, _deStart, data) ) return false; + log(Log::LineType::Information, i18n(" Verify debug executive")); + if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, _deStart, data, 0) ) return false; + for (uint i=0; i<data.count(); i++) { + if ( _deArray[_deStart+i]==data[i] ) continue; + uint inc = device()->addressIncrement(Pic::MemoryRangeType::Code); + Address address = device()->range(Pic::MemoryRangeType::Code).start + inc * (_deStart + i); + log(Log::LineType::Error, i18n("Device memory doesn't match debug executive (at address %1: reading %2 and expecting %3).") + .arg(toHexLabel(address, device()->nbCharsAddress())) + .arg(toHexLabel(data[i], device()->nbCharsWord(Pic::MemoryRangeType::Code))) + .arg(toHexLabel(_deArray[_deStart+i], device()->nbCharsWord(Pic::MemoryRangeType::Code)))); + return false; + } + return true; +} + +bool Icd2::DebugProgrammer::doProgram(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkProgram(memory) ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + // probably needed for all devices that don't have a "erase and write" mode + if ( range.all() && FAMILY_DATA[family(device()->name())].debugExec==QString("16F7X7") ) { + Pic::Memory dmemory(*device()); + dmemory.setWord(Pic::MemoryRangeType::Code, 0, 0x0028); + dmemory.setWord(Pic::MemoryRangeType::Code, 1, 0x0030); + log(Log::LineType::Information, i18n("Programming device for debugging test...")); + if ( !internalProgram(dmemory, range) ) return false; + if ( !static_cast<Debugger *>(_debugger)->init(false) ) return false; + log(Log::LineType::Information, i18n("Debugging test successful")); + } + log(Log::LineType::Information, i18n("Programming device memory...")); + if ( !internalProgram(memory, range) ) return false; + log(Log::LineType::Information, i18n("Programming successful")); + return static_cast<Debugger *>(_debugger)->init(true); +} + +bool Icd2::DebugProgrammer::programAll(const Pic::Memory &mem) +{ + Pic::Memory memory = toDebugMemory(mem, false); + if ( !programAndVerifyRange(Pic::MemoryRangeType::Code, memory) ) return false; + if ( !writeDebugExecutive() ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::DebugVector, memory) ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::Eeprom, memory) ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::UserId, memory) ) return false; + if ( device()->is18Family() ) { + if ( !hardware()->command("0C00", 0) ) return false; // #### ?? + QString com = "42" + toHex(0xFB5, 8) + toHex(1, 8); // write RSBUG (?) + if ( !hardware()->command(com, 0) ) return false; + if ( !hardware()->command("0C01", 0) ) return false; // #### ?? + } + if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, memory) ) return false; + return true; +} + +bool Icd2::DebugProgrammer::internalRead(Device::Memory *mem, const Device::MemoryRange &range, const ::Programmer::VerifyData *vd) +{ + if ( vd==0 || (vd->actions & ::Programmer::BlankCheckVerify) ) return Icd2::ProgrammerBase::internalRead(mem, range, vd); + Pic::Memory memory = toDebugMemory(static_cast<const Pic::Memory &>(vd->memory), true); + ::Programmer::VerifyData vdata(vd->actions, memory); + if ( !Icd2::ProgrammerBase::internalRead(0, range, &vdata) ) return false; + if ( range.all() && !readRange(Pic::MemoryRangeType::DebugVector, 0, &vdata) ) return false; + return true; +} + +bool Icd2::DebugProgrammer::readDebugExecutiveVersion() +{ + if ( !hardware()->getDebugExecVersion(_debugExecutiveVersion) ) return false; + log(Log::LineType::Information, i18n(" Debug executive version: %1").arg(_debugExecutiveVersion.pretty())); + return true; +} + +//---------------------------------------------------------------------------- +void Icd2::DebuggerGroup::addDevice(const QString &name, const Device::Data *ddata, ::Group::Support) +{ + if ( FAMILY_DATA[family(name)].debugExec==0 ) return; + Group::addDevice(name, ddata, data(name).debugSupport); +} + +::Debugger::Specific *Icd2::DebuggerGroup::createDebuggerSpecific(::Debugger::Base &base) const +{ + const Pic::Data *data = static_cast< ::Debugger::PicBase &>(base).device(); + if ( data==0 ) return 0; + QString debugExec = FAMILY_DATA[family(data->name())].debugExec; + switch (data->architecture().type()) { + case Pic::Architecture::P16X: + if ( debugExec=="16F872" ) return new P16F872DebuggerSpecific(base); + if ( debugExec=="16F7X7" ) return new P16F7X7DebuggerSpecific(base); + return new P16F87XDebuggerSpecific(base); + case Pic::Architecture::P17C: + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: return new P18FDebuggerSpecific(base); + case Pic::Architecture::P10X: + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: + case Pic::Architecture::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} diff --git a/src/progs/icd2/base/icd2_debug.h b/src/progs/icd2/base/icd2_debug.h new file mode 100644 index 0000000..bd2a6fe --- /dev/null +++ b/src/progs/icd2/base/icd2_debug.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 ICD2_DEBUG_H +#define ICD2_DEBUG_H + +#include "icd2_prog.h" +#include "devices/pic/prog/pic_debug.h" + +namespace Icd2 +{ +class DebuggerSpecific; + +//----------------------------------------------------------------------------- +class DebugProgrammer : public ProgrammerBase +{ +Q_OBJECT +public: + DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data); + bool readDebugExecutiveVersion(); + const VersionData &debugExecutiveVersion() const { return _debugExecutiveVersion; } + +private: + VersionData _debugExecutiveVersion; + Device::Array _deArray; + uint _deStart, _deEnd; + + virtual void clear(); + virtual bool internalSetupHardware(); + virtual bool doProgram(const Device::Memory &memory, const Device::MemoryRange &range); + virtual bool programAll(const Pic::Memory &memory); + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const ::Programmer::VerifyData *vdata); + + bool getDebugExecutive(); + bool writeDebugExecutive(); + Pic::Memory toDebugMemory(const Pic::Memory &memory, bool withDebugExecutive); +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(DebugProgrammer &programmer) : ::Debugger::PicBase(programmer) {} + virtual bool setBreakpoints(const QValueList<Address> &addresses); + Hardware *hardware() { return static_cast<Hardware *>(_programmer.hardware()); } + DebugProgrammer &programmer() { return static_cast<DebugProgrammer &>(_programmer); } + DebuggerSpecific *specific(); + bool waitForTargetMode(Pic::TargetMode mode); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + bool init(bool last); + +protected: + virtual bool internalInit(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + virtual bool updateState(); + +private: + bool _initLast; +}; + +//----------------------------------------------------------------------------- +class DebuggerGroup : public Group +{ +public: + virtual QString name() const { return "icd2_debugger"; } + virtual QString label() const { return i18n("ICD2 Debugger"); } + virtual ::Programmer::Properties properties() const { return Group::properties() | ::Programmer::Debugger; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 1; } + +protected: + virtual void addDevice(const QString &name, const Device::Data *data, ::Group::Support support); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new DebugProgrammer(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast<DebugProgrammer &>(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_debug_specific.cpp b/src/progs/icd2/base/icd2_debug_specific.cpp new file mode 100644 index 0000000..56cc178 --- /dev/null +++ b/src/progs/icd2/base/icd2_debug_specific.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 "icd2_debug_specific.h" + +#include "devices/pic/base/pic_register.h" +#include "icd2_data.h" + +//---------------------------------------------------------------------------- +Address Icd2::P16FDebuggerSpecific::addressWREG() const +{ + return FAMILY_DATA[family(device()->name())].wreg; +} + +Address Icd2::P16FDebuggerSpecific::addressRegister(Address address) const +{ + QString name = device()->registersData().sfrNames[address]; + if ( name=="FSR" ) return FAMILY_DATA[family(device()->name())].fsr; + if ( name=="STATUS" ) return FAMILY_DATA[family(device()->name())].status; + return address; +} + +bool Icd2::P16FDebuggerSpecific::reset() +{ + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + return init(true); +} + +bool Icd2::P16FDebuggerSpecific::setBreakpoint(Address address) +{ + if ( !address.isValid() ) address = 0x1FFF; // outside memory range + BitValue value = address.toUInt() | 0x8000; // read-only INBUG bit + return hardware()->writeRegister(0x18E, value, 2); +} + +bool Icd2::P16FDebuggerSpecific::readBreakpoint(BitValue &value) +{ + if ( !hardware()->readRegister(0x18E, value, 2) ) return false; + value = value.maskWith(0x1FFF); + return true; +} + +bool Icd2::P16FDebuggerSpecific::beginInit(Device::Array *saved) +{ + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + double vdd; + if ( !hardware()->readVoltage(Pic::TargetVdd, vdd) ) return false; + log(Log::DebugLevel::Normal, QString(" Target Vdd: %1 V").arg(vdd)); + + if (saved) { + saved->resize(1); + if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, 0, *saved, 0) ) return false; // save first instruction + if ( (*saved)[0]!=device()->nopInstruction() ) log(Log::LineType::Warning, i18n(" According to ICD2 manual, instruction at address 0x0 should be \"nop\".")); + } + + return true; +} + +bool Icd2::P16FDebuggerSpecific::endInit(BitValue expectedPC) +{ + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + BitValue value; + if ( !readBreakpoint(value) ) return false; + if ( value==expectedPC+1 ) { + // #### happen for some custom icd2 or sometimes when we had to force a halt (?) + expectedPC = expectedPC+1; + //log(Log::LineType::Information, i18n("Detected custom ICD2")); + } + if ( value!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4))); + return false; + } + if ( !setBreakpoint(0x0000) ) return false; + + if ( !base().update() ) return false; + if ( base().pc()!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4))); + return false; + } + return true; +} + +bool Icd2::P16F872DebuggerSpecific::init(bool) +{ + Device::Array saved; + if ( !beginInit(&saved) ) return false; + + // this seems to be needed + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false; + log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target."); + Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device + if ( !base().waitForTargetMode(Pic::TargetRunning) ) return false; + log(Log::DebugLevel::Normal, " Try to halt target."); + if ( !hardware()->haltRun() ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + log(Log::DebugLevel::Normal, " Set breakpoint at reset vector."); + if ( !setBreakpoint(0x0000) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false; + log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target."); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction + if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false; + + return endInit(0x0001); +} + +bool Icd2::P16F87XDebuggerSpecific::init(bool) +{ + Device::Array saved; + if ( !beginInit(&saved) ) return false; + + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false; + log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target."); + Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + if ( mode==Pic::TargetRunning && !hardware()->haltRun() ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + log(Log::DebugLevel::Normal, " Set breakpoint at reset vector."); + if ( !setBreakpoint(0x0000) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false; + log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target."); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction + if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false; + + return endInit(0x0001); +} + +bool Icd2::P16F7X7DebuggerSpecific::init(bool last) +{ + Device::Array saved; + if ( !beginInit(last ? &saved : 0) ) return false; + + log(Log::DebugLevel::Normal, " Run target."); + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + + BitValue value; + if ( !readBreakpoint(value) ) return false; + BitValue expectedPC = (last ? 0x0001 : 0x0000); + if ( value==expectedPC+1 ) { + expectedPC = expectedPC+1; + log(Log::DebugLevel::Normal, "Probably detected custom ICD2"); + } + if ( value!=expectedPC ) + log(Log::DebugLevel::Normal, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4))); + if ( !setBreakpoint(0x0000) ) return false; + + if ( !base().update() ) return false; + // #### not sure if there is a better way to get initial values (we are stopped here...) + Register::list().setValue(base().pcTypeData(), value); + Register::list().setValue(base().registerTypeData("STATUS"), 0x0); + Register::list().setValue(deviceSpecific()->wregTypeData(), 0x0); + + return true; +} + +//---------------------------------------------------------------------------- +Icd2::P18FDebuggerSpecific::P18FDebuggerSpecific(::Debugger::Base &base) + : DebuggerSpecific(base) +{ + const Pic::RegistersData &rdata = device()->registersData(); + // find last used bank (but not #15) + _reservedBank = rdata.nbBanks - 1; // #14 + for (uint i=1; i<rdata.nbBanks-1; i++) { + if ( rdata.isBankUsed(i) ) continue; + _reservedBank = i - 1; + break; + } + // check it's not a bank for CAN + for (; _reservedBank>0; _reservedBank--) + if ( !rdata.bankHasSfrs(_reservedBank) ) break; + // also take care of USB RAM + if ( (device()->architecture()==Pic::Architecture::P18F || device()->architecture()==Pic::Architecture::P18J) + && device()->hasFeature(Pic::Feature::USB) ) { + if ( _reservedBank==7 ) _reservedBank = 3; // 18F2455 family: 4 USB RAM banks + // 18F87J50 family ? + } +} + +Address Icd2::P18FDebuggerSpecific::addressWREG()const +{ + return reservedRegisterOffset() | 0x0FF; +} + +Address Icd2::P18FDebuggerSpecific::addressRegister(Address address) const +{ + QString name = device()->registersData().sfrNames[address]; + if ( name=="PCLATU" ) return reservedRegisterOffset() | 0x0F4; + if ( name=="PCLATH" ) return reservedRegisterOffset() | 0x0F5; + if ( name=="FSR0H" ) return reservedRegisterOffset() | 0x0FB; + if ( name=="FSR0L" ) return reservedRegisterOffset() | 0x0FC; + if ( name=="BSR" ) return reservedRegisterOffset() | 0x0FD; + if ( name=="STATUS" ) return reservedRegisterOffset() | 0x0FE; + return address; +} + +bool Icd2::P18FDebuggerSpecific::setBreakpoint(Address address) +{ + BitValue value = (address.isValid() ? address.toUInt() << 15 : 0x0FFFFF00); // ?? + return hardware()->writeRegister(0xFB6, value, 4); +} + +bool Icd2::P18FDebuggerSpecific::readBreakpoint(BitValue &value) +{ + if ( !hardware()->readRegister(0xFB6, value, 4) ) return false; + value >>= 15; + return true; +} + +bool Icd2::P18FDebuggerSpecific::reset() +{ + if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ?? + if ( !hardware()->writeRegister(0xFB5, 0x01, 1) ) return false; // #### ?? + if ( !hardware()->command("2D", 0) ) return false; // reset + if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ?? + if ( !base().update() ) return false; + BitValue expectedPC = 0x0000; + if ( base().pc()==0x0001) { + expectedPC = 0x0001; + log(Log::LineType::Information, i18n("Detected custom ICD2")); + } + if ( base().pc()!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4))); + return false; + } + return true; +} + +bool Icd2::P18FDebuggerSpecific::init(bool) +{ + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + return reset(); +} diff --git a/src/progs/icd2/base/icd2_debug_specific.h b/src/progs/icd2/base/icd2_debug_specific.h new file mode 100644 index 0000000..d14887b --- /dev/null +++ b/src/progs/icd2/base/icd2_debug_specific.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 ICD2_DEBUG_SPECIFIC_H +#define ICD2_DEBUG_SPECIFIC_H + +#include "icd2_debug.h" + +namespace Icd2 +{ +//----------------------------------------------------------------------------- +class DebuggerSpecific : public ::Debugger::Specific +{ +public: + DebuggerSpecific(::Debugger::Base &base) : ::Debugger::Specific(base) {} + Debugger &base() { return static_cast<Debugger &>(_base); } + const Debugger &base() const { return static_cast<const Debugger &>(_base); } + const Pic::Data *device() const { return base().device(); } + Hardware *hardware() { return base().programmer().hardware(); } + DebugProgrammer &programmer() { return base().programmer(); } + ::Debugger::PicSpecific *deviceSpecific() { return base().deviceSpecific(); } + virtual Address addressWREG() const = 0; + virtual BitValue maskPC() const = 0; + virtual Address addressRegister(Address address) const = 0; + virtual bool setBreakpoint(Address address) = 0; + virtual bool readBreakpoint(BitValue &value) = 0; + virtual bool init(bool last) = 0; + virtual bool reset() = 0; +}; + +//----------------------------------------------------------------------------- +class P16FDebuggerSpecific : public DebuggerSpecific +{ +public: + P16FDebuggerSpecific(::Debugger::Base &base) : DebuggerSpecific(base) {} + virtual Address addressBreakpointRegister() const { return 0x18E; } + virtual BitValue writeMaskBreakpointRegister() const { return 0x8000; } + virtual BitValue readMaskBreakpointRegister() const { return 0x1FFF; } + virtual Address addressWREG() const; + virtual BitValue maskPC() const { return 0x1FFF; } + virtual Address addressRegister(Address address) const; + virtual bool setBreakpoint(Address address); + virtual bool readBreakpoint(BitValue &value); + virtual bool reset(); + +protected: + bool beginInit(Device::Array *saved); + bool endInit(BitValue expectedPC); +}; + +class P16F872DebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F872DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +class P16F87XDebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F87XDebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +class P16F7X7DebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F7X7DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +//----------------------------------------------------------------------------- +class P18FDebuggerSpecific : public DebuggerSpecific +{ +public: + P18FDebuggerSpecific(::Debugger::Base &base); + virtual Address addressWREG() const; + virtual BitValue maskPC() const { return 0xFFFF; } + virtual Address addressRegister(Address address) const; + virtual bool setBreakpoint(Address address); + virtual bool readBreakpoint(BitValue &value); + virtual bool init(bool last); + virtual bool reset(); + uint reservedBank() const { return _reservedBank; } + +private: + uint _reservedBank; // bank where are the debugging sfrs + uint reservedRegisterOffset() const { return reservedBank() << 8; } +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_prog.cpp b/src/progs/icd2/base/icd2_prog.cpp new file mode 100644 index 0000000..7b2a59b --- /dev/null +++ b/src/progs/icd2/base/icd2_prog.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * 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 "icd2_prog.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" +#include "icd2_serial.h" +#include "icd2_usb.h" +#include "icd2_data.h" + +//----------------------------------------------------------------------------- +void Icd2::ProgrammerBase::clear() +{ + Icd::ProgrammerBase::clear(); + _firmwareId = 0; + _testData = TestData(); +} + +bool Icd2::ProgrammerBase::readFirmwareVersion() +{ + if ( !hardware()->setup() ) return false; + if ( !Icd::ProgrammerBase::readFirmwareVersion() ) return false; + _firmwareId = hardware()->getFirmwareId(); + return !hasError(); +} + +bool Icd2::ProgrammerBase::internalSetupHardware() +{ + ::Programmer::Config config; + if ( !_targetSelfPowered && device()->architecture()==Pic::Architecture::P30F + && !askContinue(i18n("It is not recommended to power dsPICs from ICD. Continue anyway?")) ) { + logUserAbort(); + return false; + } + return Icd::ProgrammerBase::internalSetupHardware(); +} + +bool Icd2::ProgrammerBase::selfTest(bool ask) +{ + log(Log::DebugLevel::Normal, " Self-test"); + if ( !hardware()->selfTest(_testData) ) return false; + if ( !_testData.pass() ) { + QString s; + for (uint i=0; i<TestData::Nb_VoltageTypes; i++) { + if ( i!=0 ) s += "; "; + s += _testData.pretty(TestData::VoltageType(i)); + } + log(Log::LineType::Warning, i18n("Self-test failed: %1").arg(s)); + if ( ask && !askContinue(i18n("Self-test failed (%1). Do you want to continue anyway?").arg(s)) ) { + logUserAbort(); + return false; + } + } + return !hasError(); +} + +VersionData Icd2::ProgrammerBase::firmwareVersion(::Programmer::FirmwareVersionType type) const +{ + const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA); + const Version &v = vd->version[_firmwareId-1]; + return VersionData(v.major, v.minor, v.dot); +} + +VersionData Icd2::ProgrammerBase::mplabVersion(::Programmer::FirmwareVersionType type) const +{ + const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA); + return VersionData(vd->mplabMajor, vd->mplabMinor, 0); +} + +bool Icd2::ProgrammerBase::setupFirmware() +{ + const FamilyData &fdata = FAMILY_DATA[family(device()->name())]; + log(Log::DebugLevel::Normal, QString(" Firmware id is %1 and we want %2").arg(_firmwareId).arg(fdata.efid)); + if ( fdata.efid==_firmwareId ) return true; + log(Log::LineType::Information, i18n(" Incorrect firmware loaded.")); + + // find firmware file + PURL::Directory dir = firmwareDirectory(); + if ( dir.isEmpty() ) return false; + QString nameFilter = "ICD" + QString::number(fdata.efid).rightJustify(2, '0') + "??????.hex"; + QStringList files = dir.files(nameFilter); + if ( files.isEmpty() ) { + log(Log::LineType::Error, i18n("Could not find firmware file \"%1\" in directory \"%2\".").arg(nameFilter).arg(dir.path())); + return false; + } + + // upload hex file + PURL::Url url(dir, files[files.count()-1]); + log(Log::DebugLevel::Normal, QString(" Firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + if ( !doUploadFirmware(file) ) return false; + + // check firmware + if ( !readFirmwareVersion() ) return false; + if ( fdata.efid!=_firmwareId ) { + log(Log::LineType::Error, i18n("Firmware still incorrect after uploading.")); + return false; + } + log(Log::LineType::Information, i18n(" Firmware succesfully uploaded.")); + return true; +} + +//----------------------------------------------------------------------------- +Icd2::Programmer::Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Icd2::ProgrammerBase(group, data, "icd2_programmer") +{} + +//---------------------------------------------------------------------------- +Programmer::Properties Icd2::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware + | ::Programmer::NeedDeviceSpecificFirmware | ::Programmer::CanReleaseReset + | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; +} + +bool Icd2::Group::canReadVoltage(Pic::VoltageType type) const +{ + return ( type==Pic::ProgrammerVpp || type==Pic::TargetVdd || type==Pic::TargetVpp ); +} + +Programmer::Hardware *Icd2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + if ( hd.port.type==PortType::Serial ) return new SerialHardware(base, hd.port.device); + return new USBHardware(base); +} + +Programmer::DeviceSpecific *Icd2::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new Icd::DeviceSpecific(base); +} diff --git a/src/progs/icd2/base/icd2_prog.h b/src/progs/icd2/base/icd2_prog.h new file mode 100644 index 0000000..e8be727 --- /dev/null +++ b/src/progs/icd2/base/icd2_prog.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * 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 ICD2_PROG_H +#define ICD2_PROG_H + +#include "common/global/global.h" +#include "icd_prog.h" +#include "icd2.h" +#include "progs/base/prog_group.h" + +namespace Icd2 +{ +class Hardware; + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Icd::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : Icd::ProgrammerBase(group, data, name) {} + Hardware *hardware() { return static_cast<Hardware *>(_hardware); } + const TestData &testData() const { return _testData; } + virtual bool selfTest(bool ask); + virtual bool readFirmwareVersion(); + uchar firmwareId() const { return _firmwareId; } + virtual bool setTarget() { return hardware()->setTarget(); } + +protected: + virtual void clear(); + virtual bool setupFirmware(); + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual VersionData mplabVersion(Programmer::FirmwareVersionType type) const; + virtual bool internalSetupHardware(); + +private: + uchar _firmwareId; + TestData _testData; +}; + +//----------------------------------------------------------------------------- +class Programmer : public ProgrammerBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data); +}; + +//----------------------------------------------------------------------------- +class Group : public Icd::Group +{ +public: + virtual QString xmlName() const { return "icd2"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetPowerModeFromConfig; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::USB ); } + virtual bool canReadVoltage(Pic::VoltageType type) const; + +protected: + virtual void initSupported(); + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +//----------------------------------------------------------------------------- +class ProgrammerGroup : public Group +{ +public: + virtual QString name() const { return "icd2"; } + virtual QString label() const { return i18n("ICD2 Programmer"); } + +protected: + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast<const Pic::Data *>(data)); } +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_serial.cpp b/src/progs/icd2/base/icd2_serial.cpp new file mode 100644 index 0000000..1ab738c --- /dev/null +++ b/src/progs/icd2/base/icd2_serial.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "icd2_serial.h" + +#include "common/global/global.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +Icd2::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedDrain | NeedFlush, log) +{} + +bool Icd2::SerialPort::open(Speed speed) +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | EnableReceiver | HardwareFlowControl, speed, 0); +} + +//----------------------------------------------------------------------------- +Icd2::SerialHardware::SerialHardware(::Programmer::Base &base, const QString &portDevice) + : Hardware(base, new SerialPort(portDevice, base)) +{} + +bool Icd2::SerialHardware::internalConnect(const QString &mode) +{ + if ( !static_cast<SerialPort *>(_port)->open(Port::Serial::S19200) ) return false; + if ( !reset() ) return false; + if ( !_port->send("Z", 1) ) return false; + QString s; + if ( !_port->receive(4, s) ) return false; + if ( !reset() ) return false; + QByteArray a = toAscii(mode); + if ( !_port->send(a.data(), a.count()) ) return false; + if ( !_port->receive(1, s) ) return false; + if ( s.upper()!=mode ) { + log(Log::LineType::Error, i18n("Failed to set port mode to '%1'.").arg(mode)); + return false; + } + //log(Log::Debug, "set fast speed"); + //if ( !setFastSpeed() ) return false; + return true; +} + +bool Icd2::SerialHardware::reset() +{ + static_cast<Port::Serial *>(_port)->setPinOn(Port::Serial::DTR, false, Port::PositiveLogic); // Trigger DTR to reset icd2 + Port::msleep(10); + static_cast<Port::Serial *>(_port)->setPinOn(Port::Serial::DTR, true, Port::PositiveLogic); // remove reset + Port::msleep(10); + return true; +} + +bool Icd2::SerialHardware::setFastSpeed() +{ + if ( !command("4D", 0) ) return false; // go faster + static_cast<SerialPort *>(_port)->open(Port::Serial::S57600); + Port::msleep(100); // ...we do need to delay here + return !hasError(); +} diff --git a/src/progs/icd2/base/icd2_serial.h b/src/progs/icd2/base/icd2_serial.h new file mode 100644 index 0000000..546e7b3 --- /dev/null +++ b/src/progs/icd2/base/icd2_serial.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 ICD2_SERIAL_H +#define ICD2_SERIAL_H + +#include "icd2.h" +#include "common/port/serial.h" + +namespace Icd2 +{ + +//----------------------------------------------------------------------------- +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(Speed speed); +}; + +//----------------------------------------------------------------------------- +class SerialHardware : public Hardware +{ +public: + SerialHardware(::Programmer::Base &base, const QString &portDevice); + +private: + bool setFastSpeed(); + bool reset(); + virtual bool internalConnect(const QString &mode); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_usb.cpp b/src/progs/icd2/base/icd2_usb.cpp new file mode 100644 index 0000000..945ef6f --- /dev/null +++ b/src/progs/icd2/base/icd2_usb.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz M�senlechner & Matthias Kranz * + * <icd2linux@hcilab.org> * + * 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 "icd2_usb.h" + +#include "microchip.h" +#include "common/common/misc.h" + +//------------------------------------------------------------------------------ +const Icd2::USBPort::SequenceData Icd2::USBPort::SEQUENCE_DATA[Nb_SequenceTypes] = { + { 0x00 }, // receive + { 0x01 }, // send + { 0x02 }, // connect + { 0x00 } // poll +}; + +Icd2::USBPort::USBPort(uint deviceId, Log::Base &log) + : Port::USB(log, Microchip::VENDOR_ID, deviceId, 1, 0), _dataSend(false) +{} + +bool Icd2::USBPort::doSequence(SequenceType type, char *data, uint size) +{ + QByteArray tx(0x12); + for (uint i=0; i<uint(tx.count()); i++) tx[i] = 0x00; + tx[0x00] = SEQUENCE_DATA[type].type; + tx[0x01] = _seqnum; + tx[0x02] = size & 0xFF; + tx[0x03] = (size >> 8) & 0xFF; + tx[0x0A] = _ctype & 0xFF; + tx[0x0B] = (_ctype >> 8) & 0xFF; + if ( !write(0x01, tx.data(), tx.size()) ) return false; + + switch (type) { + case Connect: break; + case Receive: + if ( !read(0x82, data, size, 0) ) return false; + break; + case Poll: + if ( !read(0x82, data, size, &_poll) ) return false; + break; + case Send: + if ( !write(0x01, data, size) ) return false; + break; + case Nb_SequenceTypes: Q_ASSERT(false); break; + } + + QByteArray rx(0x08); + if ( !read(0x81, rx.data(), rx.size(), 0) ) return false; + //Q_ASSERT( rx[0]==tx[1] ); + + _seqnum++; + if ( _seqnum==0xFF ) _seqnum = 0xC0; + return true; +} + +bool Icd2::USBPort::connectDevice(const QString &mode) +{ + _seqnum = 0xC1; // preset seqnum + + _ctype = 0x00; + if ( !doSequence(Connect, 0, 0) ) return false; + if ( !send("Z", 1) ) return false; + QString s; + if ( !receive(4, s) ) return false; + + _ctype = 0x00; + if ( !doSequence(Connect, 0, 0) ) return false; + for (uint i=0; true; i++) { + if ( i==10 ) { + log(Log::LineType::Error, i18n("Problem connecting ICD2: please try again after unplug-replug.")); + return false; + } + _ctype = 0x02; + QByteArray a = toAscii(mode); + if ( !doSequence(Send, a.data(), a.count()) ) return false; + char c; + _ctype = 0x02; + if ( !doSequence(Receive, &c, 1) ) return false; + if ( c==mode.lower()[0] ) break; + } + + return true; +} + +bool Icd2::USBPort::internalReceive(uint size, char *data, uint) +{ + if (_dataSend) { + //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2) + _ctype = 0xC9; + } else _ctype = 0xC9; + bool ok = doSequence(Receive, data, size); + if (_dataSend) _dataSend = false; + return ok; +} + +bool Icd2::USBPort::internalSend(const char *data, uint size, uint) +{ + if (_dataSend) { + //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2) + _ctype = 0xC9; + } else _ctype = 0xC9; + bool ok = doSequence(Send, (char *)data, size); + if (_dataSend) _dataSend = false; + return ok; +} + +bool Icd2::USBPort::poll(uint size, QString &s) +{ + QMemArray<uchar> a; + if ( !poll(size, a) ) return false; + s.fill(0, size); + for (uint i=0; i<size; i++) s[i] = a[i]; + return true; +} + +bool Icd2::USBPort::poll(uint size, QMemArray<uchar> &a) +{ + a.resize(size); + for (;;) { + _ctype = 0x65;//0x01; + if ( !doSequence(Poll, (char *)a.data(), size) ) return false; + if (_poll) break; + } + //log(Log::DebugLevel::Max, QString("Receiced: \"%1\"").arg(toPrintable((const char *)a.data(), size))); + return true; +} + +bool Icd2::USBPort::dataSend(const char *data, uint size) +{ + _dataSend = true; + return Port::USB::send(data, size); +} + +bool Icd2::USBPort::dataReceive(uint size, QString &s) +{ + _dataSend = true; + return Port::USB::receive(size, s); +} + +//------------------------------------------------------------------------------ +Icd2::USBHardware::USBHardware(::Programmer::Base &base) + : Hardware(base, new USBPort(ID_CLIENT, base)) +{} + +bool Icd2::USBHardware::internalConnect(const QString &mode) +{ + // load control messages for USB device if needed + log(Log::DebugLevel::Extra, QString("need firmware ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE)!=0)); + if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE) ) { + USBPort port(ID_FIRMWARE, *this); + if ( !port.open() ) return false; + uint i = 0; + while ( CONTROL_MESSAGE_DATA[i].bytes!=0 ) { + if ( !port.sendControlMessage(CONTROL_MESSAGE_DATA[i]) ) return false; + i++; + } + port.close(); + for (uint i=0; i<10; i++) { + log(Log::DebugLevel::Extra, QString("client here ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_CLIENT)!=0)); + if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_CLIENT) ) break; + Port::msleep(1000); + } + } + + if ( !_port->open() ) return false; + return static_cast<USBPort *>(_port)->connectDevice(mode); +} diff --git a/src/progs/icd2/base/icd2_usb.h b/src/progs/icd2/base/icd2_usb.h new file mode 100644 index 0000000..c2677a6 --- /dev/null +++ b/src/progs/icd2/base/icd2_usb.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * <icd2linux@hcilab.org> * + * 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 ICD2_USB_H +#define ICD2_USB_H + +#include "icd2.h" +#include "common/port/usb_port.h" + +namespace Icd2 +{ + +//----------------------------------------------------------------------------- +class USBPort : public Port::USB +{ +public: + USBPort(uint deviceId, Log::Base &log); + bool connectDevice(const QString &mode); + bool poll(uint size, QString &s); + bool poll(uint size, QMemArray<uchar> &data); + bool dataSend(const char *data, uint size); + bool dataReceive(uint size, QString &s); + +private: + uchar _seqnum; + bool _poll; + uint _ctype; + bool _dataSend; + + enum SequenceType { Receive = 0, Send, Connect, Poll, Nb_SequenceTypes }; + struct SequenceData { + char type; + }; + static const SequenceData SEQUENCE_DATA[Nb_SequenceTypes]; + bool doSequence(SequenceType type, char *data, uint size); + virtual bool internalSend(const char *data, uint size, uint timeout = 0); + virtual bool internalReceive(uint size, char *data, uint timeout = 0); +}; + +//------------------------------------------------------------------------------ +class USBHardware : public Hardware +{ +public: + USBHardware(::Programmer::Base &base); + +private: + static const Port::USB::ControlMessageData CONTROL_MESSAGE_DATA[]; + enum { ID_FIRMWARE = 0x8000, // ICD2 id before usb firmware is transmitted + ID_CLIENT = 0x8001 // ICD2 id after firmware is transmitted + }; + virtual bool internalConnect(const QString &mode); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_usb_firmware.cpp b/src/progs/icd2/base/icd2_usb_firmware.cpp new file mode 100644 index 0000000..c7947cf --- /dev/null +++ b/src/progs/icd2/base/icd2_usb_firmware.cpp @@ -0,0 +1,613 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * <icd2linux@hcilab.org> * + * 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 "icd2_usb.h" + +const Port::USB::ControlMessageData Icd2::USBHardware::CONTROL_MESSAGE_DATA[] = { +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x146C, "C200907FA5E05418FF131313541F4450" }, +{ 0x40, 0xA0, 0x147C, "F51C139201D2E8907FAB74FFF0907FA9" }, +{ 0x40, 0xA0, 0x148C, "F0907FAAF05391EF907F95E044C0F090" }, +{ 0x40, 0xA0, 0x149C, "7FAFE04401F0907FAEE04405F0D2AF12" }, +{ 0x40, 0xA0, 0x14AC, "175F3000FD121100C20080F622" }, +{ 0x40, 0xA0, 0x1100, "907FE9E0245D600D1470030212442402" }, +{ 0x40, 0xA0, 0x1110, "600302124A907FEAE0750800F509A3E0" }, +{ 0x40, 0xA0, 0x1120, "FEE42509F509EE3508F508907FEEE075" }, +{ 0x40, 0xA0, 0x1130, "0A00F50BA3E0FEE4250BF50BEE350AF5" }, +{ 0x40, 0xA0, 0x1140, "0A907FE8E064C060030211D4E50B450A" }, +{ 0x40, 0xA0, 0x1150, "700302124AC3E50B9440E50A94005008" }, +{ 0x40, 0xA0, 0x1160, "850A0C850B0D8006750C00750D40907F" }, +{ 0x40, 0xA0, 0x1170, "E9E0B4A325AE0CAF0DAA08A9097B01C0" }, +{ 0x40, 0xA0, 0x1180, "03C002C0017A7F790078007C7FAD03D0" }, +{ 0x40, 0xA0, 0x1190, "01D002D003121356800FAF09AE08AD0D" }, +{ 0x40, 0xA0, 0x11A0, "7A7F79007B001215A4907FB5E50DF0E5" }, +{ 0x40, 0xA0, 0x11B0, "0D2509F509E50C3508F508C3E50B950D" }, +{ 0x40, 0xA0, 0x11C0, "F50BE50A950CF50A907FB4E020E20302" }, +{ 0x40, 0xA0, 0x11D0, "114C80F4907FE8E06440706EE50B450A" }, +{ 0x40, 0xA0, 0x11E0, "6068E4907FC5F0907FB4E020E3F9907F" }, +{ 0x40, 0xA0, 0x11F0, "C5E0750C00F50D907FE9E0B4A315AE0C" }, +{ 0x40, 0xA0, 0x1200, "AF0DA809AC087D017B017A7E79C01213" }, +{ 0x40, 0xA0, 0x1210, "56800FAF09AE08AD0D7A7F79007B0012" }, +{ 0x40, 0xA0, 0x1220, "14B9E50D2509F509E50C3508F508C3E5" }, +{ 0x40, 0xA0, 0x1230, "0B950DF50BE50A950CF50A907FB4E044" }, +{ 0x40, 0xA0, 0x1240, "02F08098907FEAE0F51C" }, +{ 0x40, 0xA0, 0x124A, "22" }, +{ 0x40, 0xA0, 0x1558, "AB07AA06AC05" }, +{ 0x40, 0xA0, 0x155E, "E4FD300111EAFFAE050DEE2400F582E4" }, +{ 0x40, 0xA0, 0x156E, "34E0F583EFF0EBAE050D74002EF582E4" }, +{ 0x40, 0xA0, 0x157E, "34E0F583EBF0AF050D74002FF582E434" }, +{ 0x40, 0xA0, 0x158E, "E0F583ECF0AF1C7AE07B001217207F0A" }, +{ 0x40, 0xA0, 0x159E, "7E0012173C" }, +{ 0x40, 0xA0, 0x15A3, "22" }, +{ 0x40, 0xA0, 0x14B9, "8E0E8F0F8D108A118B12" }, +{ 0x40, 0xA0, 0x14C3, "E4F513E513C395105020050FE50FAE0E" }, +{ 0x40, 0xA0, 0x14D3, "7002050E14FFE5122513F582E43511F5" }, +{ 0x40, 0xA0, 0x14E3, "83E0FD121558051380D9" }, +{ 0x40, 0xA0, 0x14ED, "22" }, +{ 0x40, 0xA0, 0x15A4, "8E0E8F0F8D108A118B12" }, +{ 0x40, 0xA0, 0x15AE, "E4FD300112E50EFFAE050DEE2403F582" }, +{ 0x40, 0xA0, 0x15BE, "E434E0F583EFF0E50FAE050D74032EF5" }, +{ 0x40, 0xA0, 0x15CE, "82E434E0F583E50FF0AF1C7AE07B0312" }, +{ 0x40, 0xA0, 0x15DE, "1720AF1CAD10AB12AA11121704" }, +{ 0x40, 0xA0, 0x15EB, "22" }, +{ 0x40, 0xA0, 0x166E, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x167E, "005391EF907FAB7401F0D086D084D085" }, +{ 0x40, 0xA0, 0x168E, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x1644, "C0E0C083C082C085C084C08675860090" }, +{ 0x40, 0xA0, 0x1654, "7FC4E4F05391EF907FAB7404F0D086D0" }, +{ 0x40, 0xA0, 0x1664, "84D085D082D083D0E032" }, +{ 0x40, 0xA0, 0x1695, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16A5, "91EF907FAB7402F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16B5, "D083D0E032" }, +{ 0x40, 0xA0, 0x16BA, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16CA, "91EF907FAB7410F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16DA, "D083D0E032" }, +{ 0x40, 0xA0, 0x14FF, "32" }, +{ 0x40, 0xA0, 0x16DF, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16EF, "91EF907FAB7408F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16FF, "D083D0E032" }, +{ 0x40, 0xA0, 0x1767, "32" }, +{ 0x40, 0xA0, 0x1768, "32" }, +{ 0x40, 0xA0, 0x1769, "32" }, +{ 0x40, 0xA0, 0x176A, "32" }, +{ 0x40, 0xA0, 0x176B, "32" }, +{ 0x40, 0xA0, 0x176C, "32" }, +{ 0x40, 0xA0, 0x176D, "32" }, +{ 0x40, 0xA0, 0x176E, "32" }, +{ 0x40, 0xA0, 0x176F, "32" }, +{ 0x40, 0xA0, 0x1770, "32" }, +{ 0x40, 0xA0, 0x1771, "32" }, +{ 0x40, 0xA0, 0x1772, "32" }, +{ 0x40, 0xA0, 0x1773, "32" }, +{ 0x40, 0xA0, 0x1774, "32" }, +{ 0x40, 0xA0, 0x1775, "32" }, +{ 0x40, 0xA0, 0x1776, "32" }, +{ 0x40, 0xA0, 0x0043, "021500" }, +{ 0x40, 0xA0, 0x1500, "02166E0002169500021644000216DF00" }, +{ 0x40, 0xA0, 0x1510, "0216BA000214FF000217670002176800" }, +{ 0x40, 0xA0, 0x1520, "0217690002176A0002176B0002176C00" }, +{ 0x40, 0xA0, 0x1530, "02176D0002176E0002176F0002177000" }, +{ 0x40, 0xA0, 0x1540, "02177100021772000217730002177400" }, +{ 0x40, 0xA0, 0x1550, "0217750002177600" }, +{ 0x40, 0xA0, 0x173C, "8E148F15E5151515AE14700215144E60" }, +{ 0x40, 0xA0, 0x174C, "051214EE80EE22" }, +{ 0x40, 0xA0, 0x175F, "E4F51BD2E9D2AF22" }, +{ 0x40, 0xA0, 0x1619, "A907E51B7023907FA5E04480F0E925E0" }, +{ 0x40, 0xA0, 0x1629, "907FA6F08D16AF03A9077517018A1889" }, +{ 0x40, 0xA0, 0x1639, "19E4F51A751B01D322C322" }, +{ 0x40, 0xA0, 0x15EC, "A907E51B7025907FA5E04480F0E925E0" }, +{ 0x40, 0xA0, 0x15FC, "4401907FA6F08D16AF03A9077517018A" }, +{ 0x40, 0xA0, 0x160C, "188919E4F51A751B03D322C322" }, +{ 0x40, 0xA0, 0x004B, "02137F" }, +{ 0x40, 0xA0, 0x137F, "C0E0C083C082C085C084C086758600C0" }, +{ 0x40, 0xA0, 0x138F, "D075D000C000C001C002C003C006C007" }, +{ 0x40, 0xA0, 0x139F, "907FA5E030E206751B0602144E907FA5" }, +{ 0x40, 0xA0, 0x13AF, "E020E10CE51B64026006751B0702144E" }, +{ 0x40, 0xA0, 0x13BF, "AF1BEF24FE604814602C24FE60772404" }, +{ 0x40, 0xA0, 0x13CF, "600302144EAB17AA18A919AF1A051A8F" }, +{ 0x40, 0xA0, 0x13DF, "8275830012124B907FA6F0E51A651670" }, +{ 0x40, 0xA0, 0x13EF, "5E751B058059907FA6E0AB17AA18A919" }, +{ 0x40, 0xA0, 0x13FF, "AE1A8E82758300121278751B028040E5" }, +{ 0x40, 0xA0, 0x140F, "1624FEB51A07907FA5E04420F0E51614" }, +{ 0x40, 0xA0, 0x141F, "B51A0A907FA5E04440F0751B00907FA6" }, +{ 0x40, 0xA0, 0x142F, "E0AB17AA18A919AE1A8E827583001212" }, +{ 0x40, 0xA0, 0x143F, "78051A800A907FA5E04440F0751B0053" }, +{ 0x40, 0xA0, 0x144F, "91DFD007D006D003D002D001D000D0D0" }, +{ 0x40, 0xA0, 0x145F, "D086D084D085D082D083D0E032" }, +{ 0x40, 0xA0, 0x1704, "1215ECE51B24FA600E146006240770F3" }, +{ 0x40, 0xA0, 0x1714, "D322E4F51BD322E4F51BD322" }, +{ 0x40, 0xA0, 0x1720, "121619E51B24FA600E146006240770F3" }, +{ 0x40, 0xA0, 0x1730, "D322E4F51BD322E4F51BD322" }, +{ 0x40, 0xA0, 0x14EE, "7400F58690FDA57C05A3E582458370F9" }, +{ 0x40, 0xA0, 0x14FE, "22" }, +{ 0x40, 0xA0, 0x0000, "021753" }, +{ 0x40, 0xA0, 0x1753, "787FE4F6D8FD75812002146C" }, +{ 0x40, 0xA0, 0x124B, "BB010CE58229F582E5833AF583E02250" }, +{ 0x40, 0xA0, 0x125B, "06E92582F8E622BBFE06E92582F8E222" }, +{ 0x40, 0xA0, 0x126B, "E58229F582E5833AF583E49322" }, +{ 0x40, 0xA0, 0x1278, "F8BB010DE58229F582E5833AF583E8F0" }, +{ 0x40, 0xA0, 0x1288, "225006E92582C8F622BBFE05E92582C8" }, +{ 0x40, 0xA0, 0x1298, "F222" }, +{ 0x40, 0xA0, 0x129A, "E709F608DFFA8046E709F208DFFA803E" }, +{ 0x40, 0xA0, 0x12AA, "88828C83E709F0A3DFFA8032E309F608" }, +{ 0x40, 0xA0, 0x12BA, "DFFA806EE309F208DFFA806688828C83" }, +{ 0x40, 0xA0, 0x12CA, "E309F0A3DFFA805A89828A83E0A3F608" }, +{ 0x40, 0xA0, 0x12DA, "DFFA804E89828A83E0A3F208DFFA8042" }, +{ 0x40, 0xA0, 0x12EA, "80D280FA80C680D4805580F280298010" }, +{ 0x40, 0xA0, 0x12FA, "80A680EA809A80A880DA80E280CA8029" }, +{ 0x40, 0xA0, 0x130A, "88848C8589828A83E493A30586F0A305" }, +{ 0x40, 0xA0, 0x131A, "86DFF5DEF3800B89828A83E493A3F608" }, +{ 0x40, 0xA0, 0x132A, "DFF9ECFAA9F0EDFB2288848C8589828A" }, +{ 0x40, 0xA0, 0x133A, "83E0A30586F0A30586DFF6DEF480E389" }, +{ 0x40, 0xA0, 0x134A, "828A83E493A3F208DFF980D688F0ED24" }, +{ 0x40, 0xA0, 0x135A, "02B4040050CCF582EB2402B4040050C2" }, +{ 0x40, 0xA0, 0x136A, "23234582F582EF4E60B8EF60010EE582" }, +{ 0x40, 0xA0, 0x137A, "239012EA73" }, +{ 0x40, 0xA0, 0x7F92, "00" }, +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x0100, "907FE9E0700302029B14700302031724" }, +{ 0x40, 0xA0, 0x0110, "FE700302038E24FB7003020295147003" }, +{ 0x40, 0xA0, 0x0120, "02028F14700302028314700302028924" }, +{ 0x40, 0xA0, 0x0130, "0560030203E2120F7A40030203EE907F" }, +{ 0x40, 0xA0, 0x0140, "EBE024FE601914604724026003020279" }, +{ 0x40, 0xA0, 0x0150, "E50C907FD4F0E50D907FD5F00203EE90" }, +{ 0x40, 0xA0, 0x0160, "7FEAE0FF121710AA06A9077B018B498A" }, +{ 0x40, 0xA0, 0x0170, "4A894BEA49600FEE907FD4F0AF01EF90" }, +{ 0x40, 0xA0, 0x0180, "7FD5F00203EE907FB4E04401F00203EE" }, +{ 0x40, 0xA0, 0x0190, "907FEAE0FF1216E4AA06A9077B018B49" }, +{ 0x40, 0xA0, 0x01A0, "8A4A894BEA49700302026F" }, +{ 0x40, 0xA0, 0x01AB, "AB498B508A5189521217F4F553907FEE" }, +{ 0x40, 0xA0, 0x01BB, "E0FFE553D39F4003E0F553E553700302" }, +{ 0x40, 0xA0, 0x01CB, "0261754F00754E00754D00754C00E553" }, +{ 0x40, 0xA0, 0x01DB, "C394405004AF5380027F40E4FCFDFEAB" }, +{ 0x40, 0xA0, 0x01EB, "4FAA4EA94DA84CC31218625038E55225" }, +{ 0x40, 0xA0, 0x01FB, "4FF582E54E3551F583E0FF7400254FF5" }, +{ 0x40, 0xA0, 0x020B, "82E4347FF583EFF07A0079007800E54F" }, +{ 0x40, 0xA0, 0x021B, "2401F54FEA354EF54EE9354DF54DE835" }, +{ 0x40, 0xA0, 0x022B, "4CF54C80A9E553C394405004AF538002" }, +{ 0x40, 0xA0, 0x023B, "7F40907FB5EFF0E553C394405004AF53" }, +{ 0x40, 0xA0, 0x024B, "80027F40C3E5539FF553907FB4E020E2" }, +{ 0x40, 0xA0, 0x025B, "030201C680F4E4907FB5F0907FB47402" }, +{ 0x40, 0xA0, 0x026B, "F0" }, +{ 0x40, 0xA0, 0x026C, "0203EE907FB4E04401F00203EE907FB4" }, +{ 0x40, 0xA0, 0x027C, "E04401F00203EE120FA60203EE120F9A" }, +{ 0x40, 0xA0, 0x028C, "0203EE120F7C0203EE120F880203EE12" }, +{ 0x40, 0xA0, 0x029C, "0FB840030203EE907FE8E0247F602414" }, +{ 0x40, 0xA0, 0x02AC, "60312402705BA200E433FF25E0FFA202" }, +{ 0x40, 0xA0, 0x02BC, "E4334F907F00F0E4A3F0907FB57402F0" }, +{ 0x40, 0xA0, 0x02CC, "0203EEE4907F00F0A3F0907FB57402F0" }, +{ 0x40, 0xA0, 0x02DC, "0203EE907FECE0F45480FFC4540FFFE0" }, +{ 0x40, 0xA0, 0x02EC, "54072F25E024B4F582E4347FF583E054" }, +{ 0x40, 0xA0, 0x02FC, "01907F00F0E4A3F0907FB57402F00203" }, +{ 0x40, 0xA0, 0x030C, "EE907FB4E04401F00203EE120FBA4003" }, +{ 0x40, 0xA0, 0x031C, "0203EE907FE8E024FE601D2402600302" }, +{ 0x40, 0xA0, 0x032C, "03EE907FEAE0B40105C2000203EE907F" }, +{ 0x40, 0xA0, 0x033C, "B4E04401F00203EE907FEAE0703B907F" }, +{ 0x40, 0xA0, 0x034C, "ECE0F45480FFC4540FFFE054072F25E0" }, +{ 0x40, 0xA0, 0x035C, "24B4F582E4347FF583E4F0907FECE054" }, +{ 0x40, 0xA0, 0x036C, "80FF131313541FFFE054072F907FD7F0" }, +{ 0x40, 0xA0, 0x037C, "E4F550" }, +{ 0x40, 0xA0, 0x037F, "E04420F08069907FB4E04401F0806012" }, +{ 0x40, 0xA0, 0x038F, "0FBC505B907FE8E024FE60182402704F" }, +{ 0x40, 0xA0, 0x039F, "907FEAE0B40104D2008044907FB4E044" }, +{ 0x40, 0xA0, 0x03AF, "01F0803B907FEAE07020907FECE0F454" }, +{ 0x40, 0xA0, 0x03BF, "80FFC4540FFFE054072F25E024B4F582" }, +{ 0x40, 0xA0, 0x03CF, "E4347FF5837401F08015907FB4E04401" }, +{ 0x40, 0xA0, 0x03DF, "F0800C120FBE5007907FB4E04401F090" }, +{ 0x40, 0xA0, 0x03EF, "7FB4E04402F0" }, +{ 0x40, 0xA0, 0x03F5, "22" }, +{ 0x40, 0xA0, 0x0033, "0203F6" }, +{ 0x40, 0xA0, 0x03F6, "53D8EF32" }, +{ 0x40, 0xA0, 0x000B, "0203FA" }, +{ 0x40, 0xA0, 0x03FA, "C0E0C0D0C000C001C002C004C005C006" }, +{ 0x40, 0xA0, 0x040A, "C007C28C758AD1758C63D28CAF0BAE0A" }, +{ 0x40, 0xA0, 0x041A, "AD09AC087A0079007800EF2401F50BEA" }, +{ 0x40, 0xA0, 0x042A, "3EF50AE93DF509E83CF508D007D006D0" }, +{ 0x40, 0xA0, 0x043A, "05D004D002D001D000D0D0D0E032" }, +{ 0x40, 0xA0, 0x0448, "750B00750A00750900750800C28C5389" }, +{ 0x40, 0xA0, 0x0458, "F0438901758AD1758C63C2B9D2A9D28C" }, +{ 0x40, 0xA0, 0x0468, "22" }, +{ 0x40, 0xA0, 0x0469, "754400754300754200754100C203C200" }, +{ 0x40, 0xA0, 0x0479, "C202C201120F037E067F228E0C8F0D75" }, +{ 0x40, 0xA0, 0x0489, "0E06750F347510067511A8EE54E07003" }, +{ 0x40, 0xA0, 0x0499, "0205897545007546808E478F48C374F6" }, +{ 0x40, 0xA0, 0x04A9, "9FFF74069ECF2402CF3400FEE48F408E" }, +{ 0x40, 0xA0, 0x04B9, "3FF53EF53DF53CF53BF53AF539AF40AE" }, +{ 0x40, 0xA0, 0x04C9, "3FAD3EAC3DAB3CAA3BA93AA839C31218" }, +{ 0x40, 0xA0, 0x04D9, "62502CE546253CF582E53B3545F58374" }, +{ 0x40, 0xA0, 0x04E9, "CDF07A0079007800E53C2401F53CEA35" }, +{ 0x40, 0xA0, 0x04F9, "3BF53BE9353AF53AE83539F53980BE75" }, +{ 0x40, 0xA0, 0x0509, "3C00753B00753A00753900AF40AE3FAD" }, +{ 0x40, 0xA0, 0x0519, "3EAC3DAB3CAA3BA93AA839C312186250" }, +{ 0x40, 0xA0, 0x0529, "39AE3BAF3CE5482FF582EE3547F583E0" }, +{ 0x40, 0xA0, 0x0539, "FDE5462FF582EE3545F583EDF07A0079" }, +{ 0x40, 0xA0, 0x0549, "007800E53C2401F53CEA353BF53BE935" }, +{ 0x40, 0xA0, 0x0559, "3AF53AE83539F53980B185450C85460D" }, +{ 0x40, 0xA0, 0x0569, "74222480FF740634FFFEC3E50F9FF50F" }, +{ 0x40, 0xA0, 0x0579, "E50E9EF50EC3E5119FF511E5109EF510" }, +{ 0x40, 0xA0, 0x0589, "C2AFD2E843D820120448907FAFE04401" }, +{ 0x40, 0xA0, 0x0599, "F0907FAEE0441DF0D2AFC2AAC2A82001" }, +{ 0x40, 0xA0, 0x05A9, "4A200105D20B12169375440075430075" }, +{ 0x40, 0xA0, 0x05B9, "42007541007F407E927D047C00AB44AA" }, +{ 0x40, 0xA0, 0x05C9, "43A942A841C312186250D32001D07A00" }, +{ 0x40, 0xA0, 0x05D9, "79007800E5442401F544EA3543F543E9" }, +{ 0x40, 0xA0, 0x05E9, "3542F542E83541F54180CA538EF83001" }, +{ 0x40, 0xA0, 0x05F9, "05120100C20130031A120F705015C203" }, +{ 0x40, 0xA0, 0x0609, "121672200007907FD6E020E7F3121658" }, +{ 0x40, 0xA0, 0x0619, "120F75120F4C80D6" }, +{ 0x40, 0xA0, 0x0621, "22" }, +{ 0x40, 0xA0, 0x0622, "12010001FFFFFF40D804018003000000" }, +{ 0x40, 0xA0, 0x0632, "000109027400010100804B090400000E" }, +{ 0x40, 0xA0, 0x0642, "FFFFFF00070501024000010705020240" }, +{ 0x40, 0xA0, 0x0652, "00010705030240000107050402400001" }, +{ 0x40, 0xA0, 0x0662, "07050502400001070506024000010705" }, +{ 0x40, 0xA0, 0x0672, "07024000010705810240000107058202" }, +{ 0x40, 0xA0, 0x0682, "40000107058302400001070584024000" }, +{ 0x40, 0xA0, 0x0692, "01070585024000010705860240000107" }, +{ 0x40, 0xA0, 0x06A2, "058702400001040309042A034D006900" }, +{ 0x40, 0xA0, 0x06B2, "630072006F0063006800690070002000" }, +{ 0x40, 0xA0, 0x06C2, "54006500630068006E006F006C006F00" }, +{ 0x40, 0xA0, 0x06D2, "67007900200349004300440032002000" }, +{ 0x40, 0xA0, 0x06E2, "55005300420020004400650076006900" }, +{ 0x40, 0xA0, 0x06F2, "630065000000" }, +{ 0x40, 0xA0, 0x1289, "436F7079726967687420284329203230" }, +{ 0x40, 0xA0, 0x1299, "3032204D6963726F6368697020546563" }, +{ 0x40, 0xA0, 0x12A9, "686E6F6C6F67792C20496E632E000000" }, +{ 0x40, 0xA0, 0x12B9, "00004672616D65776F726B7320636F70" }, +{ 0x40, 0xA0, 0x12C9, "79726967687420284329203139393820" }, +{ 0x40, 0xA0, 0x12D9, "416E63686F722043686970732C20496E" }, +{ 0x40, 0xA0, 0x12E9, "632E0000" }, +{ 0x40, 0xA0, 0x11B5, "60C01A50FF13CBFF1507FF15DD000000" }, +{ 0x40, 0xA0, 0x11C5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11D5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11E5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11F5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1205, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1215, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1225, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1235, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1245, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1255, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1265, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1275, "00000000421B120000421B150000421B" }, +{ 0x40, 0xA0, 0x1285, "100000" }, +{ 0x40, 0xA0, 0x06F8, "8B128A138914751700751800AB12AA13" }, +{ 0x40, 0xA0, 0x0708, "A9141217F4FF7E008E158F16C3E51694" }, +{ 0x40, 0xA0, 0x0718, "40E515648094805063AE15AF16901A50" }, +{ 0x40, 0xA0, 0x0728, "75F003EF1218C3EE75F003A42583F583" }, +{ 0x40, 0xA0, 0x0738, "E0FBA3E0FAA3E0F9EA496040AB12AA13" }, +{ 0x40, 0xA0, 0x0748, "A914C003C002C001AE15AF16901A5075" }, +{ 0x40, 0xA0, 0x0758, "F003EF1218C3EE75F003A42583F583E0" }, +{ 0x40, 0xA0, 0x0768, "FBA3E0FAA3E0F989828A83D001D002D0" }, +{ 0x40, 0xA0, 0x0778, "0312077E8002E4738E178F18AE17AF18" }, +{ 0x40, 0xA0, 0x0788, "22" }, +{ 0x40, 0xA0, 0x0789, "C2AFAF0BAE0AAD09AC088F1C8E1B8D1A" }, +{ 0x40, 0xA0, 0x0799, "8C19D2AFAF1CAE1BAD1AAC1922" }, +{ 0x40, 0xA0, 0x07A6, "907FC7E4F022" }, +{ 0x40, 0xA0, 0x07AC, "8E228F23901B10E0FEA3E0FF8E248F25" }, +{ 0x40, 0xA0, 0x07BC, "901B10E522F0A3E523F0AE24AF2522" }, +{ 0x40, 0xA0, 0x07CB, "901B10E0FEA3E0FF22" }, +{ 0x40, 0xA0, 0x07D4, "901A00EBF0A3EAF0A3E9F0901A031218" }, +{ 0x40, 0xA0, 0x07E4, "86901B12E4F0A37402F0901A09E0FEA3" }, +{ 0x40, 0xA0, 0x07F4, "E0FFEF30E018901A00E0FBA3E0FAA3E0" }, +{ 0x40, 0xA0, 0x0804, "F9901A1AEBF0A3EAF0A3E9F08016901A" }, +{ 0x40, 0xA0, 0x0814, "00E0FBA3E0FAA3E0F9901A13EBF0A3EA" }, +{ 0x40, 0xA0, 0x0824, "F0A3E9F0901A1DE4F0A37401F0901A09" }, +{ 0x40, 0xA0, 0x0834, "E0FEA3E0FFEEFF7E00901A17EFF0901A" }, +{ 0x40, 0xA0, 0x0844, "03E0FCA3E0FDA3E0FEA3E0FF901A0F12" }, +{ 0x40, 0xA0, 0x0854, "18867F007E007D007C00901A0FE0F8A3" }, +{ 0x40, 0xA0, 0x0864, "E0F9A3E0FAA3E0FBD31218625003020A" }, +{ 0x40, 0xA0, 0x0874, "72120D3C901A18EEF0FEA3EFF0FFEF4E" }, +{ 0x40, 0xA0, 0x0884, "7040901B10E0FEA3E0FFEF4E60E3901A" }, +{ 0x40, 0xA0, 0x0894, "03E0FCA3E0FDA3E0FEA3E0FF901A0FE0" }, +{ 0x40, 0xA0, 0x08A4, "F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE9A" }, +{ 0x40, 0xA0, 0x08B4, "FEED99FDEC98FC901A03121886020A72" }, +{ 0x40, 0xA0, 0x08C4, "80AF901A18E0FE" }, +{ 0x40, 0xA0, 0x08CB, "A3E0FFE4FCFD901A0B121886907FE374" }, +{ 0x40, 0xA0, 0x08DB, "7EF0907FE47440F0901A09E0FEA3E0FF" }, +{ 0x40, 0xA0, 0x08EB, "EF20E0030209E2907FE5E0FF901A16EF" }, +{ 0x40, 0xA0, 0x08FB, "F0901A1DE0FEA3E0FFEF64014E600302" }, +{ 0x40, 0xA0, 0x090B, "09BE7B017A1A7916C003C002C001901A" }, +{ 0x40, 0xA0, 0x091B, "1AE0FBA3E0FAA3E0F989828A83D001D0" }, +{ 0x40, 0xA0, 0x092B, "02D0031209338002E473EF4E70030209" }, +{ 0x40, 0xA0, 0x093B, "BE901A03E0FCA3E0FDA3E0FEA3E0FFC0" }, +{ 0x40, 0xA0, 0x094B, "04C005C006C007901A18E0FEA3E0FFE4" }, +{ 0x40, 0xA0, 0x095B, "FCFDA804A905AA06AB07901A0BE0FCA3" }, +{ 0x40, 0xA0, 0x096B, "E0FDA3E0FEA3E0FFC3EF9BFBEE9AFAED" }, +{ 0x40, 0xA0, 0x097B, "99F9EC98F8901A0FE0FCA3E0FDA3E0FE" }, +{ 0x40, 0xA0, 0x098B, "A3E0FFC3EF9BFBEE9AFAED99F9EC98F8" }, +{ 0x40, 0xA0, 0x099B, "D007D006D005D004C3EF9BFFEE9AFEED" }, +{ 0x40, 0xA0, 0x09AB, "99FDEC98FC901A03121886901A1DE4F0" }, +{ 0x40, 0xA0, 0x09BB, "A3E4F0901A19E024FFF0901A18E034FF" }, +{ 0x40, 0xA0, 0x09CB, "F0" }, +{ 0x40, 0xA0, 0x09CC, "901A18E0FEA3E0FFD3EF9400EE940040" }, +{ 0x40, 0xA0, 0x09DC, "030208F28044907FE5E0FF901A13E0FB" }, +{ 0x40, 0xA0, 0x09EC, "A3E0FAA3E0F9EF12183A901A07E0FEA3" }, +{ 0x40, 0xA0, 0x09FC, "E0FF901A14EE8FF012184C901A19E024" }, +{ 0x40, 0xA0, 0x0A0C, "FFF0901A18E034FFF0901A18E0FEA3E0" }, +{ 0x40, 0xA0, 0x0A1C, "FFD3EF9400EE940050BC901A0FE0FCA3" }, +{ 0x40, 0xA0, 0x0A2C, "E0FDA3E0FEA3E0FF901A0BE0F8A3E0F9" }, +{ 0x40, 0xA0, 0x0A3C, "A3E0FAA3E0FBC3EF9BFFEE9AFEED99FD" }, +{ 0x40, 0xA0, 0x0A4C, "EC98FC901A0F121886901A0FE0FCA3E0" }, +{ 0x40, 0xA0, 0x0A5C, "FDA3E0FEA3E0FFEC4D4E4F7003020856" }, +{ 0x40, 0xA0, 0x0A6C, "1207A6020856901A03E0FCA3E0FDA3E0" }, +{ 0x40, 0xA0, 0x0A7C, "FEA3E0FF22" }, +{ 0x40, 0xA0, 0x0A81, "901A1FEBF0A3EAF0A3E9F0901A221218" }, +{ 0x40, 0xA0, 0x0A91, "86901B12E4F0A37401F0901A28E0FEA3" }, +{ 0x40, 0xA0, 0x0AA1, "E0FFEF30E018901A1FE0FBA3E0FAA3E0" }, +{ 0x40, 0xA0, 0x0AB1, "F9901A38EBF0A3EAF0A3E9F08016901A" }, +{ 0x40, 0xA0, 0x0AC1, "1FE0FBA3E0FAA3E0F9901A35EBF0A3EA" }, +{ 0x40, 0xA0, 0x0AD1, "F0A3E9F0901A28E0FEA3E0FFEEFF7E00" }, +{ 0x40, 0xA0, 0x0AE1, "901A34EFF0901A22E0FCA3E0FDA3E0FE" }, +{ 0x40, 0xA0, 0x0AF1, "A3E0FF901A2E1218867F007E007D007C" }, +{ 0x40, 0xA0, 0x0B01, "00901A2EE0F8A3E0F9A3E0FAA3E0FBD3" }, +{ 0x40, 0xA0, 0x0B11, "1218625003020D2D7F407E007D007C00" }, +{ 0x40, 0xA0, 0x0B21, "901A2EE0F8A3E0F9A3E0FAA3E0FBD312" }, +{ 0x40, 0xA0, 0x0B31, "1862400C901A2A121892000000408014" }, +{ 0x40, 0xA0, 0x0B41, "901A2EE0FCA3E0FDA3E0FEA3E0FF901A" }, +{ 0x40, 0xA0, 0x0B51, "2A121886901A2DE0FF901A32EFF0907F" }, +{ 0x40, 0xA0, 0x0B61, "B8E0FFEF30E140901B10E0FEA3E0FFEF" }, +{ 0x40, 0xA0, 0x0B71, "4E60EB901A22E0FCA3E0FDA3E0FEA3E0" }, +{ 0x40, 0xA0, 0x0B81, "FF901A2EE0F8" }, +{ 0x40, 0xA0, 0x0B87, "A3E0F9A3E0FAA3E0FBC3EF9BFFEE9AFE" }, +{ 0x40, 0xA0, 0x0B97, "ED99FDEC98FC901A22121886020D2D80" }, +{ 0x40, 0xA0, 0x0BA7, "B7907FE3747EF0907FE4E4F0901A28E0" }, +{ 0x40, 0xA0, 0x0BB7, "FEA3E0FFEF20E003020CBB7B017A1A79" }, +{ 0x40, 0xA0, 0x0BC7, "33C003C002C001901A38E0FBA3E0FAA3" }, +{ 0x40, 0xA0, 0x0BD7, "E0F989828A83D001D002D003120BE880" }, +{ 0x40, 0xA0, 0x0BE7, "02E473901A3BEEF0FEA3EFF0FFEF4E70" }, +{ 0x40, 0xA0, 0x0BF7, "03020C9B901A3BE0FEA3E0FFEF64024E" }, +{ 0x40, 0xA0, 0x0C07, "7017901A32E0FFE4FCFDFE901A2DE0FE" }, +{ 0x40, 0xA0, 0x0C17, "C3EE9FFF907FB9EFF0901A22E0FCA3E0" }, +{ 0x40, 0xA0, 0x0C27, "FDA3E0FEA3E0FFC004C005C006C00790" }, +{ 0x40, 0xA0, 0x0C37, "1A32E0FFE4FCFDFEA804A905AA06AB07" }, +{ 0x40, 0xA0, 0x0C47, "901A2AE0FCA3E0FDA3E0FEA3E0FFC3EF" }, +{ 0x40, 0xA0, 0x0C57, "9BFBEE9AFAED99F9EC98F8901A2EE0FC" }, +{ 0x40, 0xA0, 0x0C67, "A3E0FDA3E0FEA3E0FFC3EF9BFBEE9AFA" }, +{ 0x40, 0xA0, 0x0C77, "ED99F9EC98" }, +{ 0x40, 0xA0, 0x0C7C, "F8D007D006D005D004C3EF9BFFEE9AFE" }, +{ 0x40, 0xA0, 0x0C8C, "ED99FDEC98FC901A22121886020D2D90" }, +{ 0x40, 0xA0, 0x0C9C, "1A33E0FF907FE5EFF0901A32E014F090" }, +{ 0x40, 0xA0, 0x0CAC, "1A32E0FFEFD394004003020BC2803690" }, +{ 0x40, 0xA0, 0x0CBC, "1A35E0FBA3E0FAA3E0F91217F4FF907F" }, +{ 0x40, 0xA0, 0x0CCC, "E5EFF0901A26E0FEA3E0FF901A36EE8F" }, +{ 0x40, 0xA0, 0x0CDC, "F012184C901A32E014F0901A32E0FFEF" }, +{ 0x40, 0xA0, 0x0CEC, "D3940050CA901A2DE0FF907FB9EFF090" }, +{ 0x40, 0xA0, 0x0CFC, "1A2EE0FCA3E0FDA3E0FEA3E0FF901A2A" }, +{ 0x40, 0xA0, 0x0D0C, "E0F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE" }, +{ 0x40, 0xA0, 0x0D1C, "9AFEED99FDEC98FC901A2E121886020A" }, +{ 0x40, 0xA0, 0x0D2C, "FA901A22E0FCA3E0FDA3E0FEA3E0FF22" }, +{ 0x40, 0xA0, 0x0D3C, "C2AF901B15E0FEA3E0FF8E1D8F1E901B" }, +{ 0x40, 0xA0, 0x0D4C, "15E4F0A3E4F0D2AFAE1DAF1E22" }, +{ 0x40, 0xA0, 0x0D59, "8B268A278928901B12E4F0A37404F0C2" }, +{ 0x40, 0xA0, 0x0D69, "04907FB6E0FFEF30E111901B10E0FEA3" }, +{ 0x40, 0xA0, 0x0D79, "E0FFEF4E60EB020E5680E6901A3EE0FF" }, +{ 0x40, 0xA0, 0x0D89, "907E80EFF0907E81E4F0AB26AA27A928" }, +{ 0x40, 0xA0, 0x0D99, "EA49607AAB26AA27A9281217F4FF907E" }, +{ 0x40, 0xA0, 0x0DA9, "82EFF0AB26AA27A92875820175830012" }, +{ 0x40, 0xA0, 0x0DB9, "180DFF907E83EFF0AB26AA27A9287582" }, +{ 0x40, 0xA0, 0x0DC9, "0275830012180DFF907E84EFF0AB26AA" }, +{ 0x40, 0xA0, 0x0DD9, "27A92875820375830012180DFF907E85" }, +{ 0x40, 0xA0, 0x0DE9, "EFF0AB26AA27A9287582047583001218" }, +{ 0x40, 0xA0, 0x0DF9, "0DFF907E86EFF0AB26AA27A928758205" }, +{ 0x40, 0xA0, 0x0E09, "75830012180DFF907E87EFF0801E907E" }, +{ 0x40, 0xA0, 0x0E19, "82E4F0907E83E4F0907E84E4F0907E85" }, +{ 0x40, 0xA0, 0x0E29, "E4F0907E86E4F0907E87E4F0907FB774" }, +{ 0x40, 0xA0, 0x0E39, "08F0907FB6E0FFEF30E110901B10E0FE" }, +{ 0x40, 0xA0, 0x0E49, "A3E0FFEF4E60EB800480E7D204901B12" }, +{ 0x40, 0xA0, 0x0E59, "E4F0A3E4F0A20422" }, +{ 0x40, 0xA0, 0x0E61, "A2009206A2059200A20622" }, +{ 0x40, 0xA0, 0x0E6C, "A2029208A2079202A20822" }, +{ 0x40, 0xA0, 0x0E77, "A203920AA2099203A20A22" }, +{ 0x40, 0xA0, 0x0E82, "901B12E0FEA3E0FF8E298F2A901B12E4" }, +{ 0x40, 0xA0, 0x0E92, "F0A3E4F0AE29AF2A22" }, +{ 0x40, 0xA0, 0x0E9B, "901B12E0FEA3E0FF8E2B8F2C901B12E4" }, +{ 0x40, 0xA0, 0x0EAB, "F0A37401F0AE2BAF2C22" }, +{ 0x40, 0xA0, 0x0EB5, "901B12E0FEA3E0FF8E2D8F2E901B12E4" }, +{ 0x40, 0xA0, 0x0EC5, "F0A37402F0AE2DAF2E22" }, +{ 0x40, 0xA0, 0x0ECF, "901B12E0FEA3E0FF8E2F8F30901B12E4" }, +{ 0x40, 0xA0, 0x0EDF, "F0A37403F0AE2FAF3022" }, +{ 0x40, 0xA0, 0x0EE9, "901B12E0FEA3E0FF8E318F32901B12E4" }, +{ 0x40, 0xA0, 0x0EF9, "F0A37404F0AE31AF3222" }, +{ 0x40, 0xA0, 0x0F03, "907FDFE0FFEF4402FF907FDFEFF0907F" }, +{ 0x40, 0xA0, 0x0F13, "DEE0FFEF4406FF907FDEEFF0907FAD74" }, +{ 0x40, 0xA0, 0x0F23, "02F0901B147401F0901A4FE4F0C203C2" }, +{ 0x40, 0xA0, 0x0F33, "00C2029078497401F0907FDD7401F090" }, +{ 0x40, 0xA0, 0x0F43, "7FE27440F01212ED22" }, +{ 0x40, 0xA0, 0x0F4C, "901B12E0FEA3E0FFEF64034E70157B01" }, +{ 0x40, 0xA0, 0x0F5C, "7A1A793D1206F8EF4E7008901B12E4F0" }, +{ 0x40, 0xA0, 0x0F6C, "A3E4F022" }, +{ 0x40, 0xA0, 0x0F70, "121339D322" }, +{ 0x40, 0xA0, 0x0F75, "12133BD322" }, +{ 0x40, 0xA0, 0x0F7A, "D322" }, +{ 0x40, 0xA0, 0x0F7C, "907FEAE0FF901B14EFF0D322" }, +{ 0x40, 0xA0, 0x0F88, "901B14E0FF907F00EFF0907FB57401F0" }, +{ 0x40, 0xA0, 0x0F98, "D322" }, +{ 0x40, 0xA0, 0x0F9A, "907FEAE0FF901A4FEFF0D322" }, +{ 0x40, 0xA0, 0x0FA6, "901A4FE0FF907F00EFF0907FB57401F0" }, +{ 0x40, 0xA0, 0x0FB6, "D322" }, +{ 0x40, 0xA0, 0x0FB8, "D322" }, +{ 0x40, 0xA0, 0x0FBA, "D322" }, +{ 0x40, 0xA0, 0x0FBC, "D322" }, +{ 0x40, 0xA0, 0x0FBE, "D322" }, +{ 0x40, 0xA0, 0x0FC0, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x0FD0, "015391EF907FAB7401F0D086D084D085" }, +{ 0x40, 0xA0, 0x0FE0, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x0FE7, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x0FF7, "91EF907FAB7404F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x1007, "D083D0E032" }, +{ 0x40, 0xA0, 0x100C, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x101C, "91EF907FAB7402F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x102C, "D083D0E032" }, +{ 0x40, 0xA0, 0x1031, "C0E0C083C082C085C084C08675860090" }, +{ 0x40, 0xA0, 0x1041, "7FC7E4F0907FC9E4F0907FCBE4F0907F" }, +{ 0x40, 0xA0, 0x1051, "CDE4F0907FCFE4F0907FD1E4F0907FD3" }, +{ 0x40, 0xA0, 0x1061, "E4F05391EF907FAB7410F0D086D084D0" }, +{ 0x40, 0xA0, 0x1071, "85D082D083D0E032" }, +{ 0x40, 0xA0, 0x1079, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x1089, "91EF907FAB7420F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x1099, "D083D0E032" }, +{ 0x40, 0xA0, 0x109E, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x10AE, "035391EF907FAB7408F0D086D084D085" }, +{ 0x40, 0xA0, 0x10BE, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x10C5, "32" }, +{ 0x40, 0xA0, 0x10C6, "32" }, +{ 0x40, 0xA0, 0x10C7, "32" }, +{ 0x40, 0xA0, 0x10C8, "C0E0C0F0C083C082C085C084C0867586" }, +{ 0x40, 0xA0, 0x10D8, "00C0D0C000C001C002C003C004C005C0" }, +{ 0x40, 0xA0, 0x10E8, "06C007901B12E0FEA3E0FFEF8EF01218" }, +{ 0x40, 0xA0, 0x10F8, "CF11240000117C000111110002117C00" }, +{ 0x40, 0xA0, 0x1108, "03117C00040000117C907FC7E0FF7E00" }, +{ 0x40, 0xA0, 0x1118, "901B15EEF0A3EFF0805D8058907E40E0" }, +{ 0x40, 0xA0, 0x1128, "FFEFB44011907E42E0FF7E00901B10EE" }, +{ 0x40, 0xA0, 0x1138, "F0A3EFF0803E753300753400C3E53494" }, +{ 0x40, 0xA0, 0x1148, "12E533648094805026AF3474402FF582" }, +{ 0x40, 0xA0, 0x1158, "E4347EF583E0FFAE34743D2EF582E434" }, +{ 0x40, 0xA0, 0x1168, "1AF583EFF00534E5347002053380CD12" }, +{ 0x40, 0xA0, 0x1178, "0ECF80031207A65391EF907FAA7402F0" }, +{ 0x40, 0xA0, 0x1188, "D007D006D005D004D003D002D001D000" }, +{ 0x40, 0xA0, 0x1198, "D0D0D086D084D085D082D083D0F0D0E0" }, +{ 0x40, 0xA0, 0x11A8, "32" }, +{ 0x40, 0xA0, 0x11A9, "32" }, +{ 0x40, 0xA0, 0x11AA, "32" }, +{ 0x40, 0xA0, 0x11AB, "32" }, +{ 0x40, 0xA0, 0x11AC, "32" }, +{ 0x40, 0xA0, 0x11AD, "32" }, +{ 0x40, 0xA0, 0x11AE, "32" }, +{ 0x40, 0xA0, 0x11AF, "32" }, +{ 0x40, 0xA0, 0x11B0, "32" }, +{ 0x40, 0xA0, 0x11B1, "32" }, +{ 0x40, 0xA0, 0x11B2, "32" }, +{ 0x40, 0xA0, 0x11B3, "32" }, +{ 0x40, 0xA0, 0x11B4, "32" }, +{ 0x40, 0xA0, 0x12ED, "90784A7480F0C207120E6CC205120E61" }, +{ 0x40, 0xA0, 0x12FD, "907F9D74FFF0907F977447F0E4907F95" }, +{ 0x40, 0xA0, 0x130D, "F0907F9E74FBF0E4907F93F0907F9C74" }, +{ 0x40, 0xA0, 0x131D, "FFF0D2A0E4FFFE0FBF00010EBE92F8BF" }, +{ 0x40, 0xA0, 0x132D, "48F5C2A0D2A5D2A6D2A7D322" }, +{ 0x40, 0xA0, 0x1339, "D322" }, +{ 0x40, 0xA0, 0x133B, "D322" }, +{ 0x40, 0xA0, 0x133D, "8B498A4A894BE4F54CF54D1207898F51" }, +{ 0x40, 0xA0, 0x134D, "8E508D4F8C4E120789C3EF9551FFEE95" }, +{ 0x40, 0xA0, 0x135D, "50FEED954FFDEC954EFCAB38AA37A936" }, +{ 0x40, 0xA0, 0x136D, "A835C31218625008754C00754D028049" }, +{ 0x40, 0xA0, 0x137D, "30A2D3E4907F9DF0C2A5C2A7D2A7AB49" }, +{ 0x40, 0xA0, 0x138D, "AA4AA94B90000112180D30E717907F9A" }, +{ 0x40, 0xA0, 0x139D, "E0F552E92401F9E43AFA1217F4547F12" }, +{ 0x40, 0xA0, 0x13AD, "183A8097907F9AE0AB49AA4AA94B1218" }, +{ 0x40, 0xA0, 0x13BD, "3AD2A5907F9D74FFF0AE4CAF4D22" }, +{ 0x40, 0xA0, 0x13CB, "E4F54390000D12180DF53990000C1218" }, +{ 0x40, 0xA0, 0x13DB, "0DF53A90000B12180DF53B90000A1218" }, +{ 0x40, 0xA0, 0x13EB, "0DF53CAF3CAE3BAD3AAC398F388E378D" }, +{ 0x40, 0xA0, 0x13FB, "368C3590000512180DF5399000041218" }, +{ 0x40, 0xA0, 0x140B, "0DF53A90000312180DF53B9000021218" }, +{ 0x40, 0xA0, 0x141B, "0DF53C120E9B1207A6753D00753E017B" }, +{ 0x40, 0xA0, 0x142B, "FF7A13793DAF3CAE3BAD3AAC39E4901A" }, +{ 0x40, 0xA0, 0x143B, "26F0A3F0A3E53DF0A3E53EF0120A818F" }, +{ 0x40, 0xA0, 0x144B, "428E418D408C3FAB3CAA3BA93AA839C3" }, +{ 0x40, 0xA0, 0x145B, "1218626036754302854244AF42AE41AD" }, +{ 0x40, 0xA0, 0x146B, "40AC3F78081218738F45AF42AE41AD40" }, +{ 0x40, 0xA0, 0x147B, "AC3F78101218738F46AF42AE41AD40AC" }, +{ 0x40, 0xA0, 0x148B, "3F78181218738F47E4F5487B007A0079" }, +{ 0x40, 0xA0, 0x149B, "43120D59120E821207A67E007F0122" }, +{ 0x40, 0xA0, 0x14AA, "8B478A488949E4F54AF54B1207898F4F" }, +{ 0x40, 0xA0, 0x14BA, "8E4E8D4D8C4C120789C3EF954FFFEE95" }, +{ 0x40, 0xA0, 0x14CA, "4EFEED954DFDEC954CFCAB38AA37A936" }, +{ 0x40, 0xA0, 0x14DA, "A835C31218625008754A00754B018018" }, +{ 0x40, 0xA0, 0x14EA, "30A2D3C2A5C2A6AB47AA48A9491217F4" }, +{ 0x40, 0xA0, 0x14FA, "907F97F0D2A6D2A5AE4AAF4B22" }, +{ 0x40, 0xA0, 0x1507, "E4F53D90000D12180DF53990000C1218" }, +{ 0x40, 0xA0, 0x1517, "0DF53A90000B12180DF53B90000A1218" }, +{ 0x40, 0xA0, 0x1527, "0DF53CAF3CAE3BAD3AAC398F388E378D" }, +{ 0x40, 0xA0, 0x1537, "368C3590000512180DF5399000041218" }, +{ 0x40, 0xA0, 0x1547, "0DF53A90000312180DF53B9000021218" }, +{ 0x40, 0xA0, 0x1557, "0DF53C120EB51207A67BFF7A1479AAAF" }, +{ 0x40, 0xA0, 0x1567, "3CAE3BAD3AAC39E4901A07F0A3F0A3F0" }, +{ 0x40, 0xA0, 0x1577, "A304F01207D48F468E458D448C43AB3C" }, +{ 0x40, 0xA0, 0x1587, "AA3BA93AA839C31218626036753D0185" }, +{ 0x40, 0xA0, 0x1597, "463EAF46AE45AD44AC4378081218738F" }, +{ 0x40, 0xA0, 0x15A7, "3FAF46AE45AD44AC4378101218738F40" }, +{ 0x40, 0xA0, 0x15B7, "AF46AE45AD44AC4378181218738F41E4" }, +{ 0x40, 0xA0, 0x15C7, "F5427B007A00793D120D59120E821207" }, +{ 0x40, 0xA0, 0x15D7, "A67E007F0122" }, +{ 0x40, 0xA0, 0x15DD, "8B398A3A893B1212EDE4F53CFB7A0079" }, +{ 0x40, 0xA0, 0x15ED, "3C120D59120E821207A67E007F0122" }, +{ 0x40, 0xA0, 0x0043, "021600" }, +{ 0x40, 0xA0, 0x1600, "020FC00002100C00020FE70002109E00" }, +{ 0x40, 0xA0, 0x1610, "02103100021079000210C5000210C600" }, +{ 0x40, 0xA0, 0x1620, "0210C7000210C8000211A9000211AA00" }, +{ 0x40, 0xA0, 0x1630, "0211AB000211AC000211AD000211AE00" }, +{ 0x40, 0xA0, 0x1640, "0211AF000211B0000211B1000211B200" }, +{ 0x40, 0xA0, 0x1650, "0211B3000211B400" }, +{ 0x40, 0xA0, 0x1658, "907FD6E030E712E04401F07F147E0012" }, +{ 0x40, 0xA0, 0x1668, "1751907FD6E054FEF022" }, +{ 0x40, 0xA0, 0x1672, "907FD6E04480F0438701000000000022" }, +{ 0x40, 0xA0, 0x1693, "907FD6E04408F0" }, +{ 0x40, 0xA0, 0x169A, "E4F549" }, +{ 0x40, 0xA0, 0x169D, "E054FBF0" }, +{ 0x40, 0xA0, 0x16A1, "E4F549" }, +{ 0x40, 0xA0, 0x16A4, "E04408F0300B04E04402F07FDC7E0512" }, +{ 0x40, 0xA0, 0x16B4, "1751907F92E030E3077FDC7E05121751" }, +{ 0x40, 0xA0, 0x16C4, "907FAB74FFF0907FA9F0907FAAF05391" }, +{ 0x40, 0xA0, 0x16D4, "EF907FD6E054F7F0" }, +{ 0x40, 0xA0, 0x16DC, "E4F549" }, +{ 0x40, 0xA0, 0x16DF, "E04404F022" }, +{ 0x40, 0xA0, 0x16E4, "A907" }, +{ 0x40, 0xA0, 0x16E6, "AE10AF118F828E83A3E064037017AD01" }, +{ 0x40, 0xA0, 0x16F6, "19ED7001228F828E83E07C002FFDEC3E" }, +{ 0x40, 0xA0, 0x1706, "FEAF0580DF7E007F00" }, +{ 0x40, 0xA0, 0x170F, "22" }, +{ 0x40, 0xA0, 0x1710, "AD07" }, +{ 0x40, 0xA0, 0x1712, "E4FCAE0EAF0F8F828E83A3E06402702A" }, +{ 0x40, 0xA0, 0x1722, "AB040CEBB50501228F828E83A3A3E0FA" }, +{ 0x40, 0xA0, 0x1732, "A3E08A54F5556254E5546255E5556254" }, +{ 0x40, 0xA0, 0x1742, "2FFBE5543EFEAF0380CC7E007F00" }, +{ 0x40, 0xA0, 0x1750, "22" }, +{ 0x40, 0xA0, 0x1751, "8E4A8F4BE54B154BAE4A7002154A4E60" }, +{ 0x40, 0xA0, 0x1761, "0512168280EE22" }, +{ 0x40, 0xA0, 0x1682, "7400F58690FDA57C05A3E582458370F9" }, +{ 0x40, 0xA0, 0x1692, "22" }, +{ 0x40, 0xA0, 0x0000, "021768" }, +{ 0x40, 0xA0, 0x1768, "787FE4F6D8FD7581550217AF" }, +{ 0x40, 0xA0, 0x17F4, "BB010689828A83E0225002E722BBFE02" }, +{ 0x40, 0xA0, 0x1804, "E32289828A83E49322" }, +{ 0x40, 0xA0, 0x180D, "BB010CE58229F582E5833AF583E02250" }, +{ 0x40, 0xA0, 0x181D, "06E92582F8E622BBFE06E92582F8E222" }, +{ 0x40, 0xA0, 0x182D, "E58229F582E5833AF583E49322" }, +{ 0x40, 0xA0, 0x183A, "BB010689828A83F0225002F722BBFE01" }, +{ 0x40, 0xA0, 0x184A, "F322" }, +{ 0x40, 0xA0, 0x184C, "C5F0F8A3E028F0C5F0F8E58215827002" }, +{ 0x40, 0xA0, 0x185C, "1583E038F022" }, +{ 0x40, 0xA0, 0x1862, "EB9FF5F0EA9E42F0E99D42F0E89C45F0" }, +{ 0x40, 0xA0, 0x1872, "22" }, +{ 0x40, 0xA0, 0x1873, "E8600FECC313FCED13FDEE13FEEF13FF" }, +{ 0x40, 0xA0, 0x1883, "D8F122" }, +{ 0x40, 0xA0, 0x1886, "ECF0A3EDF0A3EEF0A3EFF022" }, +{ 0x40, 0xA0, 0x1892, "A8828583F0D083D0821218A91218A912" }, +{ 0x40, 0xA0, 0x18A2, "18A91218A9E473E493A3C583C5F0C583" }, +{ 0x40, 0xA0, 0x18B2, "C8C582C8F0A3C583C5F0C583C8C582C8" }, +{ 0x40, 0xA0, 0x18C2, "22" }, +{ 0x40, 0xA0, 0x18C3, "A42582F582E5F03583F58322" }, +{ 0x40, 0xA0, 0x18CF, "D083D082F8E4937012740193700DA3A3" }, +{ 0x40, 0xA0, 0x18DF, "93F8740193F5828883E473740293B5F0" }, +{ 0x40, 0xA0, 0x18EF, "067403936860E9A3A3A3A380D8" }, +{ 0x40, 0xA0, 0x1774, "020469E493A3F8E493A34003F68001F2" }, +{ 0x40, 0xA0, 0x1784, "08DFF48029E493A3F85407240CC8C333" }, +{ 0x40, 0xA0, 0x1794, "C4540F4420C8834004F456800146F6DF" }, +{ 0x40, 0xA0, 0x17A4, "E4800B01020408102040809011B5E47E" }, +{ 0x40, 0xA0, 0x17B4, "019360BCA3FF543F30E509541FFEE493" }, +{ 0x40, 0xA0, 0x17C4, "A360010ECF54C025E060A840B8E493A3" }, +{ 0x40, 0xA0, 0x17D4, "FAE493A3F8E493A3C8C582C8CAC583CA" }, +{ 0x40, 0xA0, 0x17E4, "F0A3C8C582C8CAC583CADFE9DEE780BE" }, +{ 0x40, 0xA0, 0x1288, "00" }, +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x7F92, "00" }, +{ 0, 0, 0, 0 } +}; diff --git a/src/progs/icd2/base/icd_prog.cpp b/src/progs/icd2/base/icd_prog.cpp new file mode 100644 index 0000000..6fadf06 --- /dev/null +++ b/src/progs/icd2/base/icd_prog.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * 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 "icd_prog.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" + +bool Icd::ProgrammerBase::doUploadFirmware(PURL::File &file) +{ + const Device::Data &data = *Device::lister().data("16F876"); + Pic::Memory memory(static_cast<const Pic::Data &>(data)); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\": %2.").arg(file.url().pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 16F876 inside ICD.")); + return false; + } + if ( !hardware().uploadFirmware(memory) ) { + log(Log::LineType::Error, i18n("Failed to upload firmware.")); + return false; + } + return true; +} + +bool Icd::ProgrammerBase::readFirmwareVersion() +{ + return hardware().getFirmwareVersion(_firmwareVersion); +} diff --git a/src/progs/icd2/base/icd_prog.h b/src/progs/icd2/base/icd_prog.h new file mode 100644 index 0000000..ba6d9bb --- /dev/null +++ b/src/progs/icd2/base/icd_prog.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef ICD_PROG_H +#define ICD_PROG_H + +#include "common/global/global.h" +#include "icd.h" +namespace PURL { class File; } + +namespace Icd +{ +//---------------------------------------------------------------------------- +class ProgrammerBase : public ::Programmer::PicBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : ::Programmer::PicBase(group, data, name) {} + virtual bool readFirmwareVersion(); + +protected: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } + virtual bool doUploadFirmware(PURL::File &file); +}; + +//---------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/microchip.cpp b/src/progs/icd2/base/microchip.cpp new file mode 100644 index 0000000..b5229f6 --- /dev/null +++ b/src/progs/icd2/base/microchip.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + * 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 "microchip.h" + +const uint Microchip::VENDOR_ID = 0x04d8; diff --git a/src/progs/icd2/base/microchip.h b/src/progs/icd2/base/microchip.h new file mode 100644 index 0000000..627b2ad --- /dev/null +++ b/src/progs/icd2/base/microchip.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * 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 MICROCHIP_H +#define MICROCHIP_H + +#include <qstring.h> + +namespace Microchip +{ + extern const uint VENDOR_ID; +} // namespace + +#endif diff --git a/src/progs/icd2/base/promate2.xml b/src/progs/icd2/base/promate2.xml new file mode 100644 index 0000000..9e85009 --- /dev/null +++ b/src/progs/icd2/base/promate2.xml @@ -0,0 +1,235 @@ +<!-- ************************************************************************* --> +<!-- * 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<programmer name="promate2"> + <device name="12C508" first_revision="0x039900" os="0x10" part="0x00" socket="0x60" /> + <device name="12C508A" first_revision="0x041001" os="0x10" part="0x02" socket="0x60" /> + <device name="12C509" first_revision="0x039900" os="0x10" part="0x01" socket="0x60" /> + <device name="12C509A" first_revision="0x041001" os="0x10" part="0x03" socket="0x60" /> + <device name="12C671" first_revision="0x041001" os="0x10" part="0x04" socket="0x60" /> + <device name="12C672" first_revision="0x040008" os="0x10" part="0x05" socket="0x60" /> + <device name="12CE518" first_revision="0x041105" os="0x10" part="0x06" socket="0x60" /> + <device name="12CE519" first_revision="0x041001" os="0x10" part="0x07" socket="0x60" /> + <device name="12CE673" first_revision="0x041105" os="0x10" part="0x08" socket="0x60" /> + <device name="12CE674" first_revision="0x041105" os="0x10" part="0x09" socket="0x60" /> + <device name="12CR509A" first_revision="0x042945" os="0x10" part="0x0B" socket="0x60" /> + <device name="12F508" first_revision="0x062026" os="0x10" part="0x1E" socket="0x60" /> + <device name="12F509" first_revision="0x062026" os="0x10" part="0x1F" socket="0x60" /> + <device name="12F629" first_revision="0x041105" os="0x10" part="0x11" socket="0x60" /> + <device name="12F675" first_revision="0x041105" os="0x10" part="0x12" socket="0x60" /> + <device name="12F683" first_revision="0x062021" os="0x10" part="0x1C" socket="0x60" /> + <device name="16C432" first_revision="0x054001" os="0x10" part="0x24" socket="0xC0" /> + <device name="16C433" first_revision="0x054001" os="0x10" part="0x0C" socket="0x60" /> + <device name="16C505" first_revision="0x042216" os="0x10" part="0x0A" socket="0x60" /> + <device name="16C54" first_revision="0x039900" os="0x10" part="0x00" socket="0xE0" /> + <device name="16C54C" first_revision="0x042235" os="0x10" part="0x1B" socket="0xE0" /> + <device name="16C55" first_revision="0x039900" os="0x10" part="0x04" socket="0xE0" /> + <device name="16C554" first_revision="0x039900" os="0x10" part="0x0E" socket="0xC0" /> + <device name="16C557" first_revision="0x059000" os="0x10" part="0x39" socket="0xE0" /> + <device name="16C558" first_revision="0x039900" os="0x10" part="0x10" socket="0xC0" /> + <device name="16C55A" first_revision="0x042401" os="0x10" part="0x1C" socket="0xE0" /> + <device name="16C56" first_revision="0x039900" os="0x10" part="0x05" socket="0xE0" /> + <device name="16C56A" first_revision="0x041101" os="0x10" part="0x17" socket="0xE0" /> + <device name="16C57" first_revision="0x039900" os="0x10" part="0x06" socket="0xE0" /> + <device name="16C57C" first_revision="0x042401" os="0x10" part="0x1D" socket="0xE0" /> + <device name="16C58A" first_revision="0x039900" os="0x10" part="0x08" socket="0xE0" /> + <device name="16C58B" first_revision="0x040008" os="0x10" part="0x0C" socket="0xE0" /> + <device name="16C620" first_revision="0x039900" os="0x10" part="0x01" socket="0xC0" /> + <device name="16C620A" first_revision="0x041101" os="0x10" part="0x17" socket="0xC0" /> + <device name="16C621" first_revision="0x039900" os="0x10" part="0x02" socket="0xC0" /> + <device name="16C621A" first_revision="0x041101" os="0x10" part="0x18" socket="0xC0" /> + <device name="16C622" first_revision="0x039900" os="0x10" part="0x03" socket="0xC0" /> + <device name="16C622A" first_revision="0x040008" os="0x10" part="0x19" socket="0xC0" /> + <device name="16C62A" first_revision="0x039900" os="0x10" part="0x09" socket="0xB0" /> + <device name="16C62B" first_revision="0x042235" os="0x10" part="0x1D" socket="0xB0" /> + <device name="16C63" first_revision="0x039900" os="0x10" part="0x01" socket="0xB0" /> + <device name="16C63A" first_revision="0x041105" os="0x10" part="0x19" socket="0xB0" /> + <device name="16C642" first_revision="0x039900" os="0x10" part="0x0F" socket="0xB0" /> + <device name="16C64A" first_revision="0x039900" os="0x10" part="0x0A" socket="0xB0" /> + <device name="16C65A" first_revision="0x039900" os="0x10" part="0x04" socket="0xB0" /> + <device name="16C65B" first_revision="0x041105" os="0x10" part="0x1A" socket="0xB0" /> + <device name="16C66" first_revision="0x039900" os="0x10" part="0x12" socket="0xB0" /> + <device name="16C662" first_revision="0x039900" os="0x10" part="0x11" socket="0xB0" /> + <device name="16C67" first_revision="0x039900" os="0x10" part="0x13" socket="0xB0" /> + <device name="16C71" first_revision="0x039900" os="0x10" part="0x05" socket="0xC0" /> + <device name="16C710" first_revision="0x039900" os="0x10" part="0x11" socket="0xC0" /> + <device name="16C711" first_revision="0x039900" os="0x10" part="0x12" socket="0xC0" /> + <device name="16C712" first_revision="0x050003" os="0x10" part="0x14" socket="0xC0" /> + <device name="16C715" first_revision="0x039900" os="0x10" part="0x13" socket="0xC0" /> + <device name="16C716" first_revision="0x050003" os="0x10" part="0x15" socket="0xC0" /> + <device name="16C717" first_revision="0x050036" os="0x10" part="0x23" socket="0xC0" /> + <device name="16C72" first_revision="0x039900" os="0x10" part="0x0B" socket="0xB0" /> + <device name="16C72A" first_revision="0x042235" os="0x10" part="0x1E" socket="0xB0" /> + <device name="16C73A" first_revision="0x039900" os="0x10" part="0x06" socket="0xB0" /> + <device name="16C73B" first_revision="0x041105" os="0x10" part="0x1B" socket="0xB0" /> + <device name="16C745" first_revision="0x051010" os="0x10" part="0x2F" socket="0xB0" /> + <device name="16C74A" first_revision="0x039900" os="0x10" part="0x08" socket="0xB0" /> + <device name="16C74B" first_revision="0x041105" os="0x10" part="0x1C" socket="0xB0" /> + <device name="16C76" first_revision="0x039900" os="0x10" part="0x14" socket="0xB0" /> + <device name="16C765" first_revision="0x051010" os="0x10" part="0x30" socket="0xB0" /> + <device name="16C77" first_revision="0x039900" os="0x10" part="0x15" socket="0xB0" /> + <device name="16C770" first_revision="0x050036" os="0x10" part="0x22" socket="0xC0" /> + <device name="16C771" first_revision="0x050036" os="0x10" part="0x21" socket="0xC0" /> + <device name="16C773" first_revision="0x042945" os="0x10" part="0x20" socket="0xB0" /> + <device name="16C774" first_revision="0x042236" os="0x10" part="0x1F" socket="0xB0" /> + <device name="16C781" first_revision="0x056000" os="0x10" part="0x27" socket="0xC0" /> + <device name="16C782" first_revision="0x054051" os="0x10" part="0x28" socket="0xC0" /> + <device name="16C923" first_revision="0x039900" os="0x10" part="0x00" socket="0x90" /> + <device name="16C924" first_revision="0x039900" os="0x10" part="0x01" socket="0x90" /> + <device name="16C925" first_revision="0x052031" os="0x10" part="0x02" socket="0x90" /> + <device name="16C926" first_revision="0x052031" os="0x10" part="0x03" socket="0x90" /> + <device name="16CE623" first_revision="0x042235" os="0x10" part="0x1A" socket="0xC0" /> + <device name="16CE624" first_revision="0x042235" os="0x10" part="0x1B" socket="0xC0" /> + <device name="16CE625" first_revision="0x042216" os="0x10" part="0x1C" socket="0xC0" /> + <device name="16CR54" first_revision="0x039900" os="0x10" part="0x02" socket="0xE0" /> + <device name="16CR54A" first_revision="0x039900" os="0x10" part="0x0D" socket="0xE0" /> + <device name="16CR54C" first_revision="0x042945" os="0x10" part="0x1A" socket="0xE0" /> + <device name="16CR56A" first_revision="0x041105" os="0x10" part="0x18" socket="0xE0" /> + <device name="16CR57C" first_revision="0x042945" os="0x10" part="0x1E" socket="0xE0" /> + <device name="16CR58B" first_revision="0x040008" os="0x10" part="0x19" socket="0xE0" /> + <device name="16CR62" first_revision="0x039900" os="0x10" part="0x0C" socket="0xB0" /> + <device name="16CR620A" first_revision="0x042945" os="0x10" part="0x16" socket="0xC0" /> + <device name="16CR63" first_revision="0x040008" os="0x10" part="0x16" socket="0xB0" /> + <device name="16CR64" first_revision="0x039900" os="0x10" part="0x0D" socket="0xB0" /> + <device name="16CR65" first_revision="0x040008" os="0x10" part="0x17" socket="0xB0" /> + <device name="16CR72" first_revision="0x040008" os="0x10" part="0x18" socket="0xB0" /> + <device name="16CR83" first_revision="0x039900" os="0x10" part="0x0A" socket="0xC0" /> + <device name="16CR84" first_revision="0x039900" os="0x10" part="0x0B" socket="0xC0" /> + <device name="16F505" first_revision="0x062026" os="0x10" part="0x1D" socket="0x60" /> + <device name="16F54" first_revision="0x061027" os="0x10" part="0x20" socket="0xE0" /> + <device name="16F57" first_revision="0x061027" os="0x10" part="0x21" socket="0xE0" /> + <device name="16F627" first_revision="0x051010" os="0x10" part="0x1F" socket="0xC0" /> + <device name="16F627A" first_revision="0x059005" os="0x10" part="0x2B" socket="0xC0" /> + <device name="16F628" first_revision="0x051010" os="0x10" part="0x20" socket="0xC0" /> + <device name="16F628A" first_revision="0x059005" os="0x10" part="0x2C" socket="0xC0" /> + <device name="16F630" first_revision="0x058005" os="0x10" part="0x16" socket="0x60" /> + <device name="16F636" first_revision="0x062008" os="0x10" part="0x1B" socket="0x60" /> + <device name="16F639" first_revision="0x062008" os="0x10" part="0x1B" socket="0x60" /> + <device name="16F648A" first_revision="0x059021" os="0x10" part="0x2F" socket="0xC0" /> + <device name="16F676" first_revision="0x058005" os="0x10" part="0x15" socket="0x60" /> + <device name="16F684" first_revision="0x061005" os="0x10" part="0x19" socket="0x60" /> + <device name="16F688" first_revision="0x061021" os="0x10" part="0x1A" socket="0x60" /> + <device name="16F716" first_revision="0x061010" os="0x10" part="0x30" socket="0xC0" /> + <device name="16F72" first_revision="0x056020" os="0x10" part="0x40" socket="0xB0" /> + <device name="16F73" first_revision="0x053001" os="0x10" part="0x32" socket="0xB0" /> + <device name="16F737" first_revision="0x060005" os="0x10" part="0x41" socket="0xB0" /> + <device name="16F74" first_revision="0x053001" os="0x10" part="0x33" socket="0xB0" /> + <device name="16F747" first_revision="0x060005" os="0x10" part="0x42" socket="0xB0" /> + <device name="16F76" first_revision="0x052026" os="0x10" part="0x31" socket="0xB0" /> + <device name="16F767" first_revision="0x060005" os="0x10" part="0x43" socket="0xB0" /> + <device name="16F77" first_revision="0x051010" os="0x10" part="0x2E" socket="0xB0" /> + <device name="16F777" first_revision="0x060005" os="0x10" part="0x44" socket="0xB0" /> + <device name="16F818" first_revision="0x058021" os="0x10" part="0x29" socket="0xC0" /> + <device name="16F819" first_revision="0x058021" os="0x10" part="0x2A" socket="0xC0" /> + <device name="16F83" first_revision="0x039900" os="0x10" part="0x0D" socket="0xC0" /> + <device name="16F84" first_revision="0x039900" os="0x10" part="0x0C" socket="0xC0" /> + <device name="16F84A" first_revision="0x042229" os="0x10" part="0x1D" socket="0xC0" /> + <device name="16F87" first_revision="0x059001" os="0x10" part="0x2D" socket="0xC0" /> + <device name="16F870" first_revision="0x051010" os="0x10" part="0x2B" socket="0xB0" /> + <device name="16F871" first_revision="0x051010" os="0x10" part="0x2C" socket="0xB0" /> + <device name="16F872" first_revision="0x050025" os="0x10" part="0x2A" socket="0xB0" /> + <device name="16F873" first_revision="0x042945" os="0x10" part="0x24" socket="0xB0" /> + <device name="16F873A" first_revision="0x058000" os="0x10" part="0x3F" socket="0xB0" /> + <device name="16F874" first_revision="0x042945" os="0x10" part="0x23" socket="0xB0" /> + <device name="16F874A" first_revision="0x058000" os="0x10" part="0x3E" socket="0xB0" /> + <device name="16F876" first_revision="0x042945" os="0x10" part="0x22" socket="0xB0" /> + <device name="16F876A" first_revision="0x058000" os="0x10" part="0x3D" socket="0xB0" /> + <device name="16F877" first_revision="0x042235" os="0x10" part="0x21" socket="0xB0" /> + <device name="16F877A" first_revision="0x058000" os="0x10" part="0x3C" socket="0xB0" /> + <device name="16F88" first_revision="0x059001" os="0x10" part="0x2E" socket="0xC0" /> + <device name="16HV540" first_revision="0x042945" os="0x10" part="0x1F" socket="0xE0" /> + <device name="17C42" first_revision="0x039900" os="0x12" part="0x00" socket="0xD0" /> + <device name="17C42A" first_revision="0x039900" os="0x12" part="0x01" socket="0xD0" /> + <device name="17C43" first_revision="0x039900" os="0x12" part="0x02" socket="0xD0" /> + <device name="17C44" first_revision="0x039900" os="0x12" part="0x03" socket="0xD0" /> + <device name="17C752" first_revision="0x042235" os="0x12" part="0x07" socket="0xD0" /> + <device name="17C756" first_revision="0x039900" os="0x12" part="0x06" socket="0xD0" /> + <device name="17C756A" first_revision="0x042235" os="0x12" part="0x09" socket="0xD0" /> + <device name="17C762" first_revision="0x042235" os="0x12" part="0x0A" socket="0xD0" /> + <device name="17C766" first_revision="0x042216" os="0x12" part="0x08" socket="0xD0" /> + <device name="17CR42" first_revision="0x039900" os="0x12" part="0x04" socket="0xD0" /> + <device name="17CR43" first_revision="0x039900" os="0x12" part="0x05" socket="0xD0" /> + <device name="18C242" first_revision="0x050001" os="0x11" part="0x29" socket="0xB0" /> + <device name="18C252" first_revision="0x050001" os="0x11" part="0x27" socket="0xB0" /> + <device name="18C442" first_revision="0x050001" os="0x11" part="0x28" socket="0xB0" /> + <device name="18C452" first_revision="0x050001" os="0x11" part="0x26" socket="0xB0" /> + <device name="18C601" first_revision="0x054001" os="0x11" part="0x0D" socket="0xD0" /> + <device name="18C658" first_revision="0x051010" os="0x11" part="0x0B" socket="0xD0" /> + <device name="18C801" first_revision="0x054001" os="0x11" part="0x0E" socket="0xD0" /> + <device name="18C858" first_revision="0x051010" os="0x11" part="0x0C" socket="0xD0" /> + <device name="18F1220" first_revision="0x058001" os="0x11" part="0x2E" socket="0xC0" /> + <device name="18F1320" first_revision="0x058001" os="0x11" part="0x2D" socket="0xC0" /> + <device name="18F2220" first_revision="0x057001" os="0x11" part="0x45" socket="0xB0" /> + <device name="18F2320" first_revision="0x057001" os="0x11" part="0x44" socket="0xB0" /> + <device name="18F2331" first_revision="0x061001" os="0x11" part="0x4A" socket="0xB0" /> + <device name="18F242" first_revision="0x056002" os="0x11" part="0x34" socket="0xB0" /> + <device name="18F2431" first_revision="0x061001" os="0x11" part="0x4B" socket="0xB0" /> + <device name="18F2439" first_revision="0x059005" os="0x11" part="0x46" socket="0xB0" /> + <device name="18F248" first_revision="0x056002" os="0x11" part="0x38" socket="0xB0" /> + <device name="18F2515" first_revision="0x062024" os="0x11" part="0x55" socket="0xB0" /> + <device name="18F252" first_revision="0x056002" os="0x11" part="0x35" socket="0xB0" /> + <device name="18F2525" first_revision="0x062024" os="0x11" part="0x56" socket="0xB0" /> + <device name="18F2539" first_revision="0x059005" os="0x11" part="0x47" socket="0xB0" /> + <device name="18F258" first_revision="0x056002" os="0x11" part="0x39" socket="0xB0" /> + <device name="18F2610" first_revision="0x062027" os="0x11" part="0x59" socket="0xB0" /> + <device name="18F2620" first_revision="0x062027" os="0x11" part="0x4F" socket="0xB0" /> + <device name="18F2680" first_revision="0x062004" os="0x11" part="0x52" socket="0xB0" /> + <device name="18F4220" first_revision="0x057001" os="0x11" part="0x43" socket="0xB0" /> + <device name="18F4320" first_revision="0x057001" os="0x11" part="0x42" socket="0xB0" /> + <device name="18F4331" first_revision="0x061001" os="0x11" part="0x4C" socket="0xB0" /> + <device name="18F442" first_revision="0x056002" os="0x11" part="0x36" socket="0xB0" /> + <device name="18F4431" first_revision="0x061001" os="0x11" part="0x4D" socket="0xB0" /> + <device name="18F4439" first_revision="0x059005" os="0x11" part="0x48" socket="0xB0" /> + <device name="18F448" first_revision="0x056002" os="0x11" part="0x3A" socket="0xB0" /> + <device name="18F4515" first_revision="0x062024" os="0x11" part="0x57" socket="0xB0" /> + <device name="18F452" first_revision="0x056002" os="0x11" part="0x37" socket="0xB0" /> + <device name="18F4525" first_revision="0x062024" os="0x11" part="0x58" socket="0xB0" /> + <device name="18F4539" first_revision="0x059005" os="0x11" part="0x49" socket="0xB0" /> + <device name="18F458" first_revision="0x056002" os="0x11" part="0x3B" socket="0xB0" /> + <device name="18F4610" first_revision="0x062027" os="0x11" part="0x5A" socket="0xB0" /> + <device name="18F4620" first_revision="0x061007" os="0x11" part="0x4E" socket="0xB0" /> + <device name="18F4680" first_revision="0x062004" os="0x11" part="0x51" socket="0xB0" /> + <device name="18F6410" first_revision="0x062011" os="0x11" part="0x1F" socket="0xD0" /> + <device name="18F6490" first_revision="0x062011" os="0x11" part="0x20" socket="0xD0" /> + <device name="18F6520" first_revision="0x059015" os="0x11" part="0x13" socket="0xD0" /> + <device name="18F6525" first_revision="0x060001" os="0x11" part="0x15" socket="0xD0" /> + <device name="18F6585" first_revision="0x060001" os="0x11" part="0x16" socket="0xD0" /> + <device name="18F6620" first_revision="0x057002" os="0x11" part="0x12" socket="0xD0" /> + <device name="18F6621" first_revision="0x060001" os="0x11" part="0x17" socket="0xD0" /> + <device name="18F6680" first_revision="0x060001" os="0x11" part="0x18" socket="0xD0" /> + <device name="18F6720" first_revision="0x057002" os="0x11" part="0x11" socket="0xD0" /> + <device name="18F8410" first_revision="0x062011" os="0x11" part="0x1E" socket="0xD0" /> + <device name="18F8490" first_revision="0x062011" os="0x11" part="0x1D" socket="0xD0" /> + <device name="18F8520" first_revision="0x059015" os="0x11" part="0x14" socket="0xD0" /> + <device name="18F8525" first_revision="0x060001" os="0x11" part="0x19" socket="0xD0" /> + <device name="18F8585" first_revision="0x060001" os="0x11" part="0x1A" socket="0xD0" /> + <device name="18F8620" first_revision="0x057002" os="0x11" part="0x10" socket="0xD0" /> + <device name="18F8621" first_revision="0x060001" os="0x11" part="0x1B" socket="0xD0" /> + <device name="18F8680" first_revision="0x060001" os="0x11" part="0x1C" socket="0xD0" /> + <device name="18F8720" first_revision="0x057002" os="0x11" part="0x0F" socket="0xD0" /> + <device name="30F2010" first_revision="0x060000" os="0x13" part="0x04" socket="0x50" /> + <device name="30F2011" first_revision="0x060000" os="0x13" part="0x05" socket="0x50" /> + <device name="30F2012" first_revision="0x060000" os="0x13" part="0x06" socket="0x50" /> + <device name="30F3011" first_revision="0x060000" os="0x13" part="0x08" socket="0x50" /> + <device name="30F3012" first_revision="0x060000" os="0x13" part="0x09" socket="0x50" /> + <device name="30F3013" first_revision="0x060000" os="0x13" part="0x0A" socket="0x50" /> + <device name="30F3014" first_revision="0x060000" os="0x13" part="0x0B" socket="0x50" /> + <device name="30F4011" first_revision="0x060000" os="0x13" part="0x0C" socket="0x50" /> + <device name="30F4012" first_revision="0x060000" os="0x13" part="0x0D" socket="0x50" /> + <device name="30F4013" first_revision="0x060000" os="0x13" part="0x17" socket="0x50" /> + <device name="30F5011" first_revision="0x060000" os="0x13" part="0x0E" socket="0x50" /> + <device name="30F5013" first_revision="0x060000" os="0x13" part="0x0F" socket="0x50" /> + <device name="30F5015" first_revision="0x060000" os="0x13" part="0x16" socket="0x50" /> + <device name="30F6010" first_revision="0x060000" os="0x13" part="0x10" socket="0x50" /> + <device name="30F6011" first_revision="0x060000" os="0x13" part="0x11" socket="0x50" /> + <device name="30F6012" first_revision="0x060000" os="0x13" part="0x12" socket="0x50" /> + <device name="30F6013" first_revision="0x060000" os="0x13" part="0x13" socket="0x50" /> + <device name="30F6014" first_revision="0x060000" os="0x13" part="0x14" socket="0x50" /> +</programmer>
\ No newline at end of file diff --git a/src/progs/icd2/gui/Makefile.am b/src/progs/icd2/gui/Makefile.am new file mode 100644 index 0000000..df597a0 --- /dev/null +++ b/src/progs/icd2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd2ui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libicd2ui.la + +libicd2ui_la_SOURCES = icd2_group_ui.cpp diff --git a/src/progs/icd2/gui/icd2_group_ui.cpp b/src/progs/icd2/gui/icd2_group_ui.cpp new file mode 100644 index 0000000..6f00788 --- /dev/null +++ b/src/progs/icd2/gui/icd2_group_ui.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * 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 "icd2_group_ui.h" + +#include "common/gui/misc_gui.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/icd2/base/icd2_debug.h" + +//---------------------------------------------------------------------------- +Icd2::AdvancedDialog::AdvancedDialog(ProgrammerBase &base, QWidget *parent) + : ::Programmer::PicAdvancedDialog(base, parent, "icd2_advanced_dialog") +{ + uint row = _firmwareContainer->numRows(); + QLabel *label = new QLabel(i18n("Id:"), _firmwareContainer); + _firmwareContainer->addWidget(label, row,row, 0,0); + _firmwareIdLabel = new QLabel(_firmwareContainer); + _firmwareContainer->addWidget(_firmwareIdLabel, row,row, 1,1); + row++; + + row = _programmerContainer->numRows(); + if ( base.group().properties() & ::Programmer::Debugger ) { + ButtonContainer *container = new ::Programmer::ButtonContainer(i18n("Debug Executive"), this, SLOT(updateDebugExecutive()), _programmerContainer); + _programmerContainer->addWidget(container, row,row, 0,1); + label = new QLabel(i18n("Version:"), container); + container->addWidget(label, 1,1, 0,0); + _debugExecLabel = new QLabel(container); + container->addWidget(_debugExecLabel, 1,1, 1,1); + row++; + } else _debugExecLabel = 0; + + for (uint i=0; i<TestData::Nb_VoltageTypes; i++) { + QLabel *label = new QLabel(i18n(TestData::VOLTAGE_LABELS[i]) + ":", _selfTestContainer); + _selfTestContainer->addWidget(label, 1+i,1+i, 0,0); + _tests[i] = new QLabel(_selfTestContainer); + _selfTestContainer->addWidget(_tests[i], 1+i,1+i, 1,1); + } +} + +void Icd2::AdvancedDialog::updateDebugExecutive() +{ + ::BusyCursor bc; + if ( ensureConnected() ) { + Pic::TargetMode mode; + if ( !base().getTargetMode(mode) ) return; + if ( mode==Pic::TargetInProgramming ) + MessageBox::sorry(i18n("You need to initiate debugging to read the debug executive version."), Log::Show); + else static_cast<DebugProgrammer &>(base()).readDebugExecutiveVersion(); + } + updateDisplay(); +} + +void Icd2::AdvancedDialog::updateDisplay() +{ + ::Programmer::PicAdvancedDialog::updateDisplay(); + uchar id = base().firmwareId(); + _firmwareIdLabel->setText(id==0 ? "---" : toHexLabel(id, 2)); + if (_debugExecLabel) { + const VersionData &vd = static_cast<DebugProgrammer &>(base()).debugExecutiveVersion(); + _debugExecLabel->setText(vd.isValid() ? vd.pretty() : "---"); + } + for (uint i=0; i<TestData::Nb_VoltageTypes; i++) + _tests[i]->setText(base().testData().result(TestData::VoltageType(i))); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Icd2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Icd2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new AdvancedDialog(static_cast<ProgrammerBase &>(base), parent); +} diff --git a/src/progs/icd2/gui/icd2_group_ui.h b/src/progs/icd2/gui/icd2_group_ui.h new file mode 100644 index 0000000..93d66e7 --- /dev/null +++ b/src/progs/icd2/gui/icd2_group_ui.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * 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 ICD2_GROUP_UI_H +#define ICD2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/icd2/base/icd2_prog.h" + +namespace Icd2 +{ +class ProgrammerBase; +class Group; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(ProgrammerBase &base, QWidget *parent); + virtual void updateDisplay(); + +private slots: + void updateDebugExecutive(); + +private: + QLabel *_firmwareIdLabel, *_debugExecLabel; + QLabel *_tests[TestData::Nb_VoltageTypes]; + ProgrammerBase &base() { return static_cast<ProgrammerBase &>(_base); } +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/icd2.pro b/src/progs/icd2/icd2.pro new file mode 100644 index 0000000..a67dbb2 --- /dev/null +++ b/src/progs/icd2/icd2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = icd2_data xml base diff --git a/src/progs/icd2/icd2_data/Makefile.am b/src/progs/icd2/icd2_data/Makefile.am new file mode 100644 index 0000000..4c5b34e --- /dev/null +++ b/src/progs/icd2/icd2_data/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd2data_la_LDFLAGS = -no-undefined $(all_libraries) +noinst_LTLIBRARIES = libicd2data.la +libicd2data_la_SOURCES = icd2_data.cpp diff --git a/src/progs/icd2/icd2_data/icd2_data.cpp b/src/progs/icd2/icd2_data/icd2_data.cpp new file mode 100644 index 0000000..ba3f5ce --- /dev/null +++ b/src/progs/icd2/icd2_data/icd2_data.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "progs/icd2/base/icd2_data.h" + +const Icd2::FirmwareVersionData Icd2::MIN_VERSION_DATA = { + 7, 21, // MPLAB 7.21 + {{ 2, 6, 5 }, // 01 + { 0, 0, 0 }, // 02 [none] + { 0, 0, 0 }, // 03 [none] + { 2, 6, 6 }, // 04 + { 1, 2, 5 }, // 05 + { 1, 2, 2 }, // 06 + { 1, 2, 9 }, // 07 + { 1, 3, 4 }, // 08 + { 1, 0, 0 }, // 09 + { 1, 3, 1 }, // 10 + { 0, 0, 27 }, // 11 + { 1, 2, 0 }, // 12 + { 0, 0, 0 }, // 13 [none] + { 0, 0, 0 }, // 14 + { 0, 0, 0 }} // 15 +}; + +const Icd2::FirmwareVersionData Icd2::MAX_VERSION_DATA = { + 7, 41, // MPLAB 7.41 + {{ 2, 7, 0 }, // 01 + { 0, 0, 0 }, // 02 [none] + { 0, 0, 0 }, // 03 [none] + { 2, 6, 8 }, // 04 + { 1, 3, 9 }, // 05 + { 1, 2, 2 }, // 06 + { 1, 4, 0 }, // 07 + { 1, 5, 0 }, // 08 + { 1, 0, 0 }, // 09 + { 1, 4, 4 }, // 10 + { 1, 0, 4 }, // 11 + { 1, 2, 0 }, // 12 + { 0, 0, 0 }, // 13 [none] + { 2, 0, 6 }, // 14 + { 1, 1, 0 }} // 15 +}; + +const Icd2::FamilyData Icd2::FAMILY_DATA[] = { + { "12F629", 1, "12F629", 0x0300, 0x0DF, 0x0DE, 0x0D4/*?*/ }, // 12F629/675 + { "16F676", 1, "16F676", 0x0300, 0x0DF, 0x0DE, 0x0D4/*?*/ }, // 16F630/676 + { "16F648A", 1, "16F648A", 0x0F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F627A/628A/648A + { "16F716", 1, "16F716", 0x0700, 0x06F, 0x06E, 0x0F0/*?*/ }, + { "16F7X7", 1, "16F7X7", 0x1F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F737/747/767/777 + { "16F819", 1, "16F819", 0x0700, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F818/819 + { "16F88", 1, "16F88", 0x0F00, 0x1EF, 0x1EE, 0x1F0/*?*/ }, // 16F87/88 + { "16F872", 1, "16F872", 0x0700, 0x1BF, 0x1BE, 0x1F0 }, // 16F870/871/872 + { "16F874", 1, "16F874", 0x0F00, 0x1FF, 0x1FE, 0x17F/*?*/ }, // 16F873/873A/874/874A + { "16F877", 1, "16F877", 0x1F00, 0x1EF, 0x1EE, 0x1F0/*?*/ }, // 16F876/876A/877/877A + { "16F7X", 1, 0, 0, 0, 0, 0 }, // 16F73 + { 0, 2, 0, 0, 0, 0, 0 }, // 30F for revision A2 (legacy: not in MPLAB 7) + { 0, 3, "30F", 0, 0, 0, 0 }, // 30F for revision A3/B0 (legacy: not in MPLAB 7) + { "18F_4", 4, "", 0, 0, 0, 0 }, // debug executive filename is computed at runtime + { "18F_5", 5, "", 0, 0, 0, 0 }, // debug executive filename is computed at runtime + { "18CX01", 6, 0,/*"18CX01"*/0, 0, 0, 0 }, // 16C601/801 + { "10F2XX", 7, 0, 0, 0, 0, 0 }, + { "16F5X", 7, 0, 0, 0, 0, 0 }, // 16F505/506 + { "12F635", 8, "12F635", 0x0700, 0x06F, 0x06E, 0x0F0/*?*/ }, // 12F635/683 16F636/639 + { "16F785", 8, "16F916", 0x0700, 0x06F, 0x06E, 0x1F0/*?*/ }, // 16F785 + { "16F916", 8, "16F916", 0x1F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F913/914/916/917/946 + { "16F684", 8, "16F684", 0x0700, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F684 + { "16F688", 8, "16F688", 0x0F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F685/687/688/689/690 + { "16F677", 8, 0, 0, 0, 0, 0 }, // 16F677 + { "16F629", 9, 0, 0, 0, 0, 0 }, // 16F629 + { "30F", 10, 0/*"30F_REVB"*/,0, 0, 0, 0 }, // 30F revision B1 and above + { "18F_J", 11, 0, 0, 0, 0, 0 }, // 18FXXJXX (?) + { "16F72", 12, 0, 0, 0, 0, 0 }, // 16F72/8X/627/628/84A + { "24F", 14, 0/*"24F"*/,0, 0, 0, 0 }, // from MPLAB 7.3 + { "33F", 14, 0/*"33F"*/,0, 0, 0, 0 }, // from MPLAB 7.3 + { "16F61X", 15, 0, 0, 0, 0, 0 }, // 12F61X/16F61X + + { 0, 0, 0, 0, 0, 0, 0 } +}; diff --git a/src/progs/icd2/icd2_data/icd2_data.pro b/src/progs/icd2/icd2_data/icd2_data.pro new file mode 100644 index 0000000..e53d0ab --- /dev/null +++ b/src/progs/icd2/icd2_data/icd2_data.pro @@ -0,0 +1,5 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd2data +SOURCES += icd2_data.cpp diff --git a/src/progs/icd2/xml/Makefile.am b/src/progs/icd2/xml/Makefile.am new file mode 100644 index 0000000..52af4ee --- /dev/null +++ b/src/progs/icd2/xml/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_icd2_parser +xml_icd2_parser_SOURCES = xml_icd2_parser.cpp +OBJECTS = $(top_builddir)/src/progs/icd2/icd2_data/libicd2data.la \ + $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_icd2_parser_DEPENDENCIES = $(OBJECTS) +xml_icd2_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/icd2/xml/xml.pro b/src/progs/icd2/xml/xml.pro new file mode 100644 index 0000000..a9a5d97 --- /dev/null +++ b/src/progs/icd2/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_icd2_parser +SOURCES += xml_icd2_parser.cpp +LIBS += ../icd2_data/libicd2data.a ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_icd2_parser +unix:QMAKE_CLEAN += ../base/icd2_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_icd2_parser.exe +win32:QMAKE_CLEAN += ..\base\icd2_data.cpp diff --git a/src/progs/icd2/xml/xml_icd2_parser.cpp b/src/progs/icd2/xml/xml_icd2_parser.cpp new file mode 100644 index 0000000..7ce2ad9 --- /dev/null +++ b/src/progs/icd2/xml/xml_icd2_parser.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "progs/icd2/base/icd2_data.h" + +//----------------------------------------------------------------------------- +namespace Icd2 +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("icd2", "Icd2") {} + +private: + virtual uint familyIndex(const QString &family) const; + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +uint Icd2::XmlToData::familyIndex(const QString &family) const +{ + uint i = 0; + for (; Icd2::FAMILY_DATA[i].efid!=0; i++) + if ( family==Icd2::FAMILY_DATA[i].name ) break; + if ( Icd2::FAMILY_DATA[i].efid==0 ) qFatal(QString("Family \"%1\" is unknown").arg(family)); + return i; +} + +void Icd2::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.famid = fromHexLabel(element.attribute("famid"), 2, &ok); + if ( !ok ) qFatal("Missing or malformed famid attribute"); + data.debugSupport = extractSupport(element.attribute("debug_support_type")); +} + +void Icd2::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << toHexLabel(data.famid, 2) << ", "; + s << "::Group::Support::Type(" << data.debugSupport.type() << ")"; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Icd2::XmlToData) diff --git a/src/progs/list/Makefile.am b/src/progs/list/Makefile.am new file mode 100644 index 0000000..9cc833f --- /dev/null +++ b/src/progs/list/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libproglistui.la libproglistnoui.la +libproglistui_la_LDFLAGS = $(all_libraries) +libproglistui_la_SOURCES = prog_list.cpp prog_list_ui.cpp +libproglistnoui_la_LDFLAGS = $(all_libraries) +libproglistnoui_la_SOURCES = prog_list.cpp prog_list_noui.cpp diff --git a/src/progs/list/list.pro b/src/progs/list/list.pro new file mode 100644 index 0000000..d6711fd --- /dev/null +++ b/src/progs/list/list.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progslist +HEADERS += prog_list.h +SOURCES += prog_list.cpp prog_list_noui.cpp diff --git a/src/progs/list/prog_list.cpp b/src/progs/list/prog_list.cpp new file mode 100644 index 0000000..eb69472 --- /dev/null +++ b/src/progs/list/prog_list.cpp @@ -0,0 +1,15 @@ +/*************************************************************************** + * 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 "prog_list.h" + +namespace Programmer +{ + Lister _lister; + const Lister &lister() { return _lister; } +} diff --git a/src/progs/list/prog_list.h b/src/progs/list/prog_list.h new file mode 100644 index 0000000..204fbaa --- /dev/null +++ b/src/progs/list/prog_list.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROG_LIST_H +#define PROG_LIST_H + +#include "common/common/lister.h" +#include "progs/base/prog_group.h" + +namespace Programmer +{ + +class Lister : public ::Group::Lister<Group> +{ +public: + Lister(); + const Group &defaultGroup(Property property); +}; +extern const Lister &lister(); + +} // namespace + +#endif diff --git a/src/progs/list/prog_list_noui.cpp b/src/progs/list/prog_list_noui.cpp new file mode 100644 index 0000000..f7ec669 --- /dev/null +++ b/src/progs/list/prog_list_noui.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * 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 "prog_list.h" + +#include "progs/direct/base/direct_prog.h" +#include "progs/icd2/base/icd2_prog.h" +#include "progs/icd2/base/icd2_debug.h" +#include "progs/icd1/base/icd1_prog.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit1/base/pickit1_prog.h" +#include "progs/psp/base/psp_prog.h" +#include "progs/gpsim/base/gpsim_debug.h" +#include "progs/picdem_bootloader/base/picdem_bootloader_prog.h" +#include "progs/pickit2_bootloader/base/pickit2_bootloader_prog.h" +#include "progs/tbl_bootloader/base/tbl_bootloader_prog.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" + +Programmer::Lister::Lister() +{ + addGroup(new Direct::DGroup, 0); + addGroup(new Icd2::ProgrammerGroup, 0); + addGroup(new Icd2::DebuggerGroup, 0); + addGroup(new Icd1::Group, 0); + addGroup(new Pickit2::Group, 0); + //addGroup(new Pickit2V2::Group, 0); + addGroup(new Pickit1::Group, 0); + addGroup(new Psp::Group, 0); + addGroup(new GPSim::Group, 0); + addGroup(new PicdemBootloader::Group, 0); + addGroup(new Pickit2Bootloader::Group, 0); + addGroup(new TinyBootloader::Group, 0); +} diff --git a/src/progs/list/prog_list_ui.cpp b/src/progs/list/prog_list_ui.cpp new file mode 100644 index 0000000..6f57a42 --- /dev/null +++ b/src/progs/list/prog_list_ui.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 "prog_list.h" + +#include "progs/direct/base/direct_prog.h" +#include "progs/direct/gui/direct_config_widget.h" +#include "progs/icd2/base/icd2_prog.h" +#include "progs/icd2/base/icd2_debug.h" +#include "progs/icd2/gui/icd2_group_ui.h" +#include "progs/icd1/base/icd1_prog.h" +#include "progs/icd1/gui/icd1_group_ui.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit2/gui/pickit2_group_ui.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" +#include "progs/pickit2v2/gui/pickit2v2_group_ui.h" +#include "progs/pickit1/base/pickit1_prog.h" +#include "progs/pickit1/gui/pickit1_group_ui.h" +#include "progs/psp/base/psp_prog.h" +#include "progs/psp/gui/psp_group_ui.h" +#include "progs/gpsim/base/gpsim_debug.h" +#include "progs/gpsim/gui/gpsim_group_ui.h" +#include "progs/picdem_bootloader/base/picdem_bootloader_prog.h" +#include "progs/picdem_bootloader/gui/picdem_bootloader_ui.h" +#include "progs/pickit2_bootloader/base/pickit2_bootloader_prog.h" +#include "progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h" +#include "progs/tbl_bootloader/base/tbl_bootloader_prog.h" +#include "progs/tbl_bootloader/gui/tbl_bootloader_ui.h" + +Programmer::Lister::Lister() +{ + addGroup(new Direct::DGroup, new Direct::GroupUI); + addGroup(new Icd2::ProgrammerGroup, new Icd2::GroupUI); + addGroup(new Icd2::DebuggerGroup, new Icd2::GroupUI); + addGroup(new Icd1::Group, new Icd1::GroupUI); + addGroup(new Pickit2::Group, new Pickit2::GroupUI); + //addGroup(new Pickit2V2::Group, new Pickit2V2::GroupUI); + addGroup(new Pickit1::Group, new Pickit1::GroupUI); + addGroup(new Psp::Group, new Psp::GroupUI); + addGroup(new GPSim::Group, new GPSim::GroupUI); + addGroup(new PicdemBootloader::Group, new PicdemBootloader::GroupUI); + addGroup(new Pickit2Bootloader::Group, new Pickit2Bootloader::GroupUI); + addGroup(new TinyBootloader::Group, new TinyBootloader::GroupUI); +} diff --git a/src/progs/manager/Makefile.am b/src/progs/manager/Makefile.am new file mode 100644 index 0000000..565dae5 --- /dev/null +++ b/src/progs/manager/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libprogmanager_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogmanager.la +libprogmanager_la_SOURCES = breakpoint.cpp debug_manager.cpp prog_manager.cpp diff --git a/src/progs/manager/breakpoint.cpp b/src/progs/manager/breakpoint.cpp new file mode 100644 index 0000000..15e08e0 --- /dev/null +++ b/src/progs/manager/breakpoint.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 "breakpoint.h" + +#include "coff/base/coff.h" + +//---------------------------------------------------------------------------- +namespace Breakpoint +{ + List *_list = 0; +} +Breakpoint::List &Breakpoint::list() +{ + if ( _list==0 ) _list = new List; + return *_list; +} + +void Breakpoint::List::append(const Data &data) +{ + Q_ASSERT( !contains(data) ); + StateData sdata; + sdata.data = data; + _list.append(sdata); + delayedChanged(); +} + +void Breakpoint::List::remove(const Data &data) +{ + Q_ASSERT( contains(data) ); + _list.remove(find(data)); + delayedChanged(); +} + +void Breakpoint::List::clear() +{ + _list.clear(); + delayedChanged(); +} + +QValueList<Breakpoint::List::StateData>::iterator Breakpoint::List::find(const Data &data) +{ + QValueList<StateData>::iterator it; + for (it=_list.begin(); it!=_list.end(); ++it) + if ( (*it).data==data ) return it; + return _list.end(); +} + +QValueList<Breakpoint::List::StateData>::const_iterator Breakpoint::List::find(const Data &data) const +{ + QValueList<StateData>::const_iterator it; + for (it=_list.begin(); it!=_list.end(); ++it) + if ( (*it).data==data ) return it; + return _list.end(); +} + +void Breakpoint::List::setState(const Data &data, State state) +{ + Q_ASSERT( contains(data) ); + (*find(data)).state = state; + delayedChanged(); +} + +void Breakpoint::List::setAddress(const Data &data, Address address) +{ + Q_ASSERT( contains(data) ); + (*find(data)).address = address; + delayedChanged(); +} diff --git a/src/progs/manager/breakpoint.h b/src/progs/manager/breakpoint.h new file mode 100644 index 0000000..fca0570 --- /dev/null +++ b/src/progs/manager/breakpoint.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * 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 BREAKPOINT_H +#define BREAKPOINT_H + +#include "common/common/storage.h" +#include "common/global/purl.h" +#include "devices/base/generic_device.h" + +namespace Breakpoint +{ +class List; +enum State { Unknown, Active, Disabled }; +enum MarkType { ProgramCounterActive = 0, ProgramCounterDisabled, + BreakpointActive, BreakpointDisabled, BreakpointReached, + BreakpointInvalid, Nb_MarkTypes }; + +//---------------------------------------------------------------------------- +class Data { +public: + Data(const PURL::Url &purl = PURL::Url(), uint pline = 0) : url(purl), line(pline) {} + bool operator <(const Data &data) const { return ( url<data.url || line<data.line ); } + bool operator ==(const Data &data) const { return ( url==data.url && line==data.line ); } + PURL::Url url; + uint line; +}; +extern void updateActions(const Data *data); + +//---------------------------------------------------------------------------- +class List; +extern List &list(); + +class List : public GenericStorage +{ +Q_OBJECT +public: + List() {} + void append(const Data &data); + void remove(const Data &data); + void clear(); + uint count() const { return _list.count(); } + const Data &data(uint i) const { return _list[i].data; } + bool contains(const Data &data) const { return find(data)!=_list.end(); } + State state(const Data &data) const { return (*find(data)).state; } + Address address(const Data &data) const { return (*find(data)).address; } + void setState(const Data &data, State state); + void setAddress(const Data &data, Address address); + +private: + class StateData { + public: + StateData() : state(Unknown) {} + Data data; + Address address; + State state; + }; + QValueList<StateData> _list; + QValueList<StateData>::const_iterator find(const Data &data) const; + QValueList<StateData>::iterator find(const Data &data); +}; + +} // namespace + +#endif diff --git a/src/progs/manager/debug_manager.cpp b/src/progs/manager/debug_manager.cpp new file mode 100644 index 0000000..7889432 --- /dev/null +++ b/src/progs/manager/debug_manager.cpp @@ -0,0 +1,392 @@ +/*************************************************************************** + * 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 "debug_manager.h" + +#include <qtimer.h> +#include <qeventloop.h> + +#include "coff/base/text_coff.h" +#include "coff/base/cdb_parser.h" +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_group.h" +#include "devices/base/register.h" +#include "progs/base/debug_config.h" +#include "prog_manager.h" + +Debugger::Manager *Debugger::manager = 0; + +Debugger::Manager::Manager() + : QObject(Programmer::manager, "debug_manager"), Log::Base(Programmer::manager), GenericView(Breakpoint::list()), + _coff(0), _data(0) +{ + connect(&_runTimer, SIGNAL(timeout()), SLOT(slotRunTimeout())); + connect(&_stepTimer, SIGNAL(timeout()), SLOT(doStep())); +} + +Debugger::Manager::~Manager() +{ + delete _coff; +} + +bool Debugger::Manager::isStepping() const +{ + return (programmer() ? programmer()->state()==Programmer::Halted : false) && _stepTimer.isActive(); +} + +Debugger::Base *Debugger::Manager::debugger() const +{ + return (programmer() ? programmer()->debugger() : 0); +} + +void Debugger::Manager::updateDevice() +{ + const Device::Data *data = deviceData(); + if ( data==_data ) return; + _data = data; + Register::list().clearWatched(); + clear(); +} + +bool Debugger::Manager::checkState(bool &first) +{ + if ( programmer()->state()==Programmer::NotConnected ) { + if ( !prepareDebugging() ) return false; + if ( !programmer()->connectHardware() ) return false; + } + first = ( debugger()->hasError() || programmer()->state()==Programmer::Stopped ); + if (first) { + log(Log::LineType::Normal, "--------------------------------------------------"); + programmer()->debugger()->setCoff(_coff); + if ( !programmer()->debugger()->init() ) return false; + } + return true; +} + +bool Debugger::Manager::init() +{ + if ( !internalInit() ) return false; + return update(true); +} + +bool Debugger::Manager::internalInit() +{ + clear(); + if ( !coffUrl().exists() ) return false; + Log::Base log; + log.setView(compileView()); + log.log(Log::LineType::Information, i18n("Parsing COFF file: %1").arg(coffUrl().pretty())); + _coff = new Coff::TextObject(_data, coffUrl()); + if ( !_coff->parse(log) ) { + delete _coff; + _coff = 0; + return false; + } + computeBreakpointAddresses(); + return true; +} + +void Debugger::Manager::clearBreakpoints() +{ + Breakpoint::list().clear(); +} + +void Debugger::Manager::freeActiveBreakpoint() +{ + uint nb = 0; + Breakpoint::Data last; + for (uint i=0; i<Breakpoint::list().count(); i++) { + const Breakpoint::Data &data = Breakpoint::list().data(i); + if ( Breakpoint::list().state(data)!=Breakpoint::Active ) continue; + nb++; + last = data; + } + uint max = programmerGroup()->maxNbBreakpoints(deviceData()); + Q_ASSERT( nb<=max && max!=0 ); + if ( nb==max ) { + log(Log::LineType::Warning, i18n("The number of active breakpoints is higher than the maximum for the current debugger (%1): disabling the last breakpoint.").arg(max)); + Breakpoint::list().setState(last, Breakpoint::Disabled); + } +} + +BitValue Debugger::Manager::pc() const +{ + return (debugger() ? debugger()->pc() : BitValue()); +} + +Breakpoint::MarkType Debugger::Manager::breakpointType(const Breakpoint::Data &data) const +{ + if ( _coff==0 ) return Breakpoint::BreakpointDisabled; + Address address = Breakpoint::list().address(data); + if ( !address.isValid() ) return Breakpoint::BreakpointInvalid; + if ( Breakpoint::list().state(data)!=Breakpoint::Active ) return Breakpoint::BreakpointDisabled; + if ( address==pc() ) { + if ( programmer()->state()==::Programmer::Halted ) return Breakpoint::BreakpointReached; + return Breakpoint::ProgramCounterDisabled; + } + return Breakpoint::BreakpointActive; +} + +bool Debugger::Manager::checkBreakpoint(const Breakpoint::Data &bdata, bool onlyWarn, Address &address) +{ + address = Address(); + if ( _coff==0 ) return true; + QValueVector<Address> addresses = _coff->addresses(bdata.url, bdata.line); + if ( addresses.isEmpty() ) { + QString s = i18n("Breakpoint at non-code line."); + if (onlyWarn) log(Log::LineType::Warning, s); + else sorry(s); + return false; + } + if ( addresses.count()>1 ) log(Log::LineType::Warning, i18n("Breakpoint corresponds to several addresses. Using the first one.")); + address = addresses[0]; + return true; +} + +void Debugger::Manager::computeBreakpointAddresses() +{ + if ( programmerGroup()==0 ) return; + int nb = programmerGroup()->maxNbBreakpoints(deviceData()); + for (int i=Breakpoint::list().count()-1; i>=0; i--) { + const Breakpoint::Data &data = Breakpoint::list().data(i); + Address address; + checkBreakpoint(data, true, address); + Breakpoint::list().setAddress(data, address); + if ( _coff==0 ) Breakpoint::list().setState(data, Breakpoint::Unknown); + else if ( Breakpoint::list().address(data).isValid() && nb>0 ) { + Breakpoint::list().setState(data, Breakpoint::Active); + nb--; + } + } +} + +QValueList<Address> Debugger::Manager::activeBreakpointAddresses() const +{ + QValueList<Address> addresses; + for (uint i=0; i<Breakpoint::list().count(); i++) { + const Breakpoint::Data &data = Breakpoint::list().data(i); + if ( Breakpoint::list().state(data)==Breakpoint::Active ) addresses.append(Breakpoint::list().address(data)); + } + return addresses; +} + +void Debugger::Manager::clear() +{ + _runTimer.stop(); + _stepTimer.stop(); + if ( programmer() ) programmer()->clear(); + delete _coff; + _coff = 0; + _currentSourceLines.clear(); + computeBreakpointAddresses(); + update(true); +} + +bool Debugger::Manager::update(bool gotoPC) +{ + _readRegisters.clear(); + if ( !updateRegisters() ) return false; + if ( debugger() ) emit statusChanged(debugger()->statusString()); + else emit statusChanged(QString::null); + _currentSourceLines.clear(); + if (_coff) _currentSourceLines = _coff->sourceLinesForAddress(pc().toUInt()); + updateView(gotoPC); + return true; +} + +bool Debugger::Manager::updateRegister(const Register::TypeData &data) +{ + // read related registers + const Device::RegistersData *rdata = deviceData()->registersData(); + Q_ASSERT(rdata); + QValueList<Register::TypeData> related = rdata->relatedRegisters(data); + for (uint k=0; k<uint(related.count()); k++) + if ( !readRegister(related[k]) ) return false; + // read port status + if ( data.type()==Register::Regular ) { + int index = rdata->portIndex(data.address()); + if ( index!=-1 ) { + QMap<uint, Device::PortBitData> data; + if ( !debugger()->updatePortStatus(index, data) ) return false; + Register::list().setPortData(index, data); + } + } + return true; +} + +bool Debugger::Manager::updateRegisters() +{ + if ( programmer()==0 || programmer()->state()!=Programmer::Halted ) return true; + QValueList<Register::TypeData> watched = Register::list().watched(); + for (uint i=0; i<uint(watched.count()); i++) + if ( !updateRegister(watched[i]) ) return false; + return true; +} + +bool Debugger::Manager::run() +{ + _stepTimer.stop(); + _runTimer.stop(); + bool first; + if ( !checkState(first) ) return false; + if ( !debugger()->setBreakpoints(activeBreakpointAddresses()) ) return false; + if ( !debugger()->run() ) return false; + log(Log::LineType::Information, i18n("Running...")); + if ( !update(true) ) return false; + _runTimer.start(programmer()->runUpdateWait()); + return true; +} + +bool Debugger::Manager::halt() +{ + _stepTimer.stop(); + _runTimer.stop(); + if ( !debugger()->halt() ) return false; + return update(true); +} + +bool Debugger::Manager::reset() +{ + _stepTimer.stop(); + _runTimer.stop(); + log(Log::LineType::Normal, "--------------------------------------------------"); + if ( !debugger()->reset() ) return false; + return doStep(true, false); +} + +bool Debugger::Manager::checkIfContinueStepping(bool &continueStepping) +{ + continueStepping = false; + if ( !readConfigEntry(Config::OnlyStopOnSourceLine).toBool() ) return true; + if ( !update(false) ) return false; + QMap<PURL::Url, uint>::const_iterator it; + for (it=_currentSourceLines.begin(); it!=_currentSourceLines.end(); ++it) { + PURL::FileGroup group = it.key().fileType().data().group; + if ( group!=PURL::Source && group!=PURL::Header ) continue; + if ( !it.key().exists() ) continue; + if ( readConfigEntry(Config::OnlyStopOnProjectSourceLine).toBool() && !isProjectSource(it.key()) ) continue; + QValueVector<Address> addresses = _coff->addresses(it.key(), it.data()); + qHeapSort(addresses); + Q_ASSERT( addresses.count()!=0 ); + if ( pc()!=addresses[0] ) continue; // we only break if pc is on the first instruction of the source line + break; + } + continueStepping = ( it==_currentSourceLines.end() ); + return true; +} + +bool Debugger::Manager::doStep(bool first, bool continued) +{ + if ( programmer()->state()!=Programmer::Halted ) return true; // has been stopped + if ( continued && !_stepTimer.isActive() ) return true; // has been stopped + _stepTimer.stop(); + if ( !first && !debugger()->step() ) return false; + bool continueStepping; + if ( !checkIfContinueStepping(continueStepping) ) return false; + if (continueStepping) _stepTimer.start(0); + else updateView(true); + return true; +} + +bool Debugger::Manager::step() +{ + bool first; + if ( !checkState(first) ) return false; + if ( !debugger()->setBreakpoints(activeBreakpointAddresses()) ) return false; + log(Log::LineType::Information, i18n("Step")); + programmer()->setState(Programmer::Halted); + return doStep(first, false); +} + +void Debugger::Manager::slotRunTimeout() +{ + if ( programmer()->state()!=Programmer::Running ) return; // has been stopped + if ( !_runTimer.isActive() ) return; // has been stopped + _runTimer.stop(); + if ( !debugger()->update() ) return; + if ( programmer()->state()==Programmer::Running ) { + _runTimer.start(programmer()->runUpdateWait()); + return; + } + log(Log::LineType::Information, i18n("Reached breakpoint.")); + update(true); + emit targetStateChanged(); +} + +void Debugger::Manager::setRegisterWatched(const Register::TypeData &data, bool watched) +{ + if (watched) { + if ( Register::list().isWatched(data) ) return; + Register::list().setWatched(data, true); + if ( programmer() && programmer()->state()==Programmer::Halted ) updateRegister(data); + } else Register::list().setWatched(data, false); +} + +bool Debugger::Manager::readRegister(const Register::TypeData &data) +{ + Q_ASSERT( data.type()==Register::Regular || data.type()==Register::Special ); + if ( _readRegisters.contains(data) ) return true; + BitValue value; + if ( !debugger()->readRegister(data, value) ) return false; + Register::list().setValue(data, value); + _readRegisters.append(data); + return true; +} + +bool Debugger::Manager::writeRegister(const Register::TypeData &data, BitValue value) +{ + Q_ASSERT( data.type()==Register::Regular || data.type()==Register::Special ); + if ( !debugger()->writeRegister(data, value) ) return false; + _readRegisters.clear(); + if ( !updateRegister(data) ) return false; + emit statusChanged(debugger()->statusString()); + return true; +} + +bool Debugger::Manager::readAllRegisters() +{ + const Device::RegistersData *rdata = _data->registersData(); + for (uint i=0; i<rdata->nbRegisters(); i++) { + Register::TypeData rtd(rdata->addressFromIndex(i), rdata->nbChars()); + if ( !updateRegister(rtd) ) return false; + } + return true; +} + +void Debugger::Manager::stopWatchAll() +{ + Register::list().clearWatched(); +} + +bool Debugger::Manager::prepareDebugging() +{ + if ( programmerGroup()->isSoftware() && programmerGroup()->isDebugger() ) { + PURL::Url curl = coffUrl(); + if ( curl.isEmpty() ) { + log(Log::LineType::Error, i18n("Cannot start debugging session without input file (not specified).")); + return false; + } + PURL::Url first; + uint i = 0; + for (; i<Programmer::Nb_InputFileTypes; i++) { + PURL::FileType type = Programmer::INPUT_FILE_TYPE_DATA[i]; + if ( !programmerGroup()->isInputFileTypeSupported(type) ) continue; + PURL::Url url = curl.toFileType(type); + if ( first.isEmpty() ) first = url; + if ( !url.exists() ) continue; + debugger()->setupInput(type, url.directory().path(), url.filename()); + break; + } + if ( i==Programmer::Nb_InputFileTypes ) { + log(Log::LineType::Error, i18n("Cannot start debugging session without input file (%1).").arg(first.pretty())); + return false; + } + } + return true; +} diff --git a/src/progs/manager/debug_manager.h b/src/progs/manager/debug_manager.h new file mode 100644 index 0000000..90b8584 --- /dev/null +++ b/src/progs/manager/debug_manager.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * 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 DEBUG_MANAGER_H +#define DEBUG_MANAGER_H + +#include <qtimer.h> + +#include "common/global/log.h" +#include "common/global/purl.h" +#include "common/common/storage.h" +#include "devices/base/generic_device.h" +#include "devices/base/register.h" +#include "breakpoint.h" +#include "prog_manager.h" +#include "progs/base/generic_debug.h" +namespace Coff { class TextObject; } +namespace CDB { class Object; } + +namespace Debugger +{ +class Manager : public QObject, public Log::Base, public GenericView +{ +Q_OBJECT +public: + Manager(); + virtual ~Manager(); + virtual PURL::Url coffUrl() const = 0; + virtual const Programmer::Group *programmerGroup() const = 0; + Programmer::Base *programmer() const { return Programmer::manager->programmer(); } + virtual const Device::Data *deviceData() const = 0; + Debugger::Base *debugger() const; + virtual void updateDevice(); + bool prepareDebugging(); + bool init(); + const Coff::TextObject *coff() const { return _coff; } + virtual void clear(); + Breakpoint::MarkType breakpointType(const Breakpoint::Data &data) const; + bool run(); + bool halt(); + bool reset(); + bool step(); + bool readRegister(const Register::TypeData &data); + bool writeRegister(const Register::TypeData &data, BitValue value); + BitValue pc() const; + bool isStepping() const; + +public slots: + void clearBreakpoints(); + virtual bool update(bool gotoPC); + void setRegisterWatched(const Register::TypeData &data, bool watched); + bool readAllRegisters(); + void stopWatchAll(); + +signals: + void statusChanged(const QString &text); + void targetStateChanged(); + void actionMessage(const QString &text); + +protected: + Coff::TextObject *_coff; + QMap<PURL::Url, uint> _currentSourceLines; + + void freeActiveBreakpoint(); + bool checkBreakpoint(const Breakpoint::Data &bdata, bool onlyWarn, Address &address); + bool updateRegisters(); + virtual bool internalInit(); + virtual bool checkState(bool &first); + virtual Log::View *compileView() = 0; + virtual bool isProjectSource(const PURL::Url &url) const = 0; + virtual bool checkIfContinueStepping(bool &continueStepping); + +private slots: + void slotRunTimeout(); + bool doStep(bool first = false, bool continued = true); + +private: + const Device::Data *_data; + QTimer _runTimer, _stepTimer; + QValueList<Register::TypeData> _readRegisters; + + void computeBreakpointAddresses(); + QValueList<Address> activeBreakpointAddresses() const; + void updateBreakpointsDisplay(); + virtual void updateView() { updateView(false); } + virtual void updateView(bool gotoPC) = 0; + bool updateRegister(const Register::TypeData &data); +}; + +extern Manager *manager; + +} // namespace + +#endif diff --git a/src/progs/manager/manager.pro b/src/progs/manager/manager.pro new file mode 100644 index 0000000..44b80d0 --- /dev/null +++ b/src/progs/manager/manager.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progmanager +HEADERS += breakpoint.h prog_manager.h debug_manager.h +SOURCES += breakpoint.cpp prog_manager.cpp debug_manager.cpp diff --git a/src/progs/manager/prog_manager.cpp b/src/progs/manager/prog_manager.cpp new file mode 100644 index 0000000..bc824c9 --- /dev/null +++ b/src/progs/manager/prog_manager.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 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 "prog_manager.h" + +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_config.h" +#include "debug_manager.h" + +//---------------------------------------------------------------------------- +Programmer::Manager *Programmer::manager = 0; + +Programmer::Manager::Manager(QObject *parent) + : QObject(parent, "programmer_manager"), _programmer(0) +{} + +Programmer::Manager::~Manager() +{ + delete _programmer; +} + +void Programmer::Manager::clear() +{ + delete _programmer; + _programmer = 0; +} + +void Programmer::Manager::createProgrammer(const Device::Data *data, const HardwareDescription &hd) +{ + if ( _programmer && _programmer->device()==data && !hasError() ) return; + delete _programmer; + _programmer = group().createProgrammer(isTargetSelfPowered(), data, hd); + _programmer->Log::Base::setParent(this); + connect(_programmer, SIGNAL(actionMessage(const QString &)), SIGNAL(actionMessage(const QString &))); + connect(&_programmer->progressMonitor(), SIGNAL(setLabel(const QString &)), SIGNAL(actionMessage(const QString &))); + connect(&_programmer->progressMonitor(), SIGNAL(setTotalProgress(uint)), SIGNAL(setTotalProgress(uint))); + connect(&_programmer->progressMonitor(), SIGNAL(setProgress(uint)), SIGNAL(setProgress(uint))); + connect(&_programmer->progressMonitor(), SIGNAL(showProgress(bool)), SIGNAL(showProgress(bool))); +} + +bool Programmer::Manager::initProgramming(bool debugging) +{ + if ( !internalInitProgramming(debugging) ) return false; + setState(Programming); + return true; +} + +bool Programmer::Manager::internalInitProgramming(bool) +{ + if ( device()==0 ) { + sorry(i18n("You need to specify the device for programming.")); + return false; + } + if ( !group().isSupported(device()->name()) ) { + if ( group().isSoftware() && group().supportedDevices().isEmpty() ) + sorry(i18n("Could not detect supported devices for \"%1\". Please check installation.").arg(group().label())); + else sorry(i18n("The current programmer \"%1\" does not support device \"%2\".").arg(group().label()).arg(device()->name())); + return false; + } + createProgrammer(device()); + return true; +} + +void Programmer::Manager::endProgramming() +{ + ::Debugger::manager->update(true); + setState(Idle); +} + +bool Programmer::Manager::program(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->program(memory, range); + endProgramming(); + if ( ok && !group().isDebugger() && readConfigEntry(Config::RunAfterProgram).toBool() ) return run(); + return ok; +} + +bool Programmer::Manager::verify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->verify(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::read(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->read(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::erase(const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->erase(range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::blankCheck(const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->blankCheck(range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::connectDevice() +{ + if ( !initProgramming(false) ) return false; + _programmer->disconnectHardware(); + bool ok = ::Debugger::manager->prepareDebugging(); + if (ok) ok = _programmer->connectDevice(); + if ( ok && group().isSoftware() && group().isDebugger() ) { + ok = _programmer->debugger()->init(); + if (ok) ::Debugger::manager->update(true); + } + endProgramming(); + return ok; +} + +bool Programmer::Manager::setDevicePower(bool on) +{ + if ( !initProgramming(false) ) return false; + bool ok = true; + if ( _programmer->isTargetSelfPowered() ) + sorry(i18n("Cannot toggle target power since target is self-powered."), QString::null); + else { + emit actionMessage(i18n("Toggle Device Power...")); + ok = _programmer->setTargetPowerOn(on); + } + endProgramming(); + return ok; +} + +bool Programmer::Manager::disconnectDevice() +{ + ::Debugger::manager->clear(); + emit actionMessage(i18n("Disconnecting...")); + bool debugger = group().isDebugger(); + _programmer->setTargetPowerOn(false); + _programmer->disconnectHardware(); + endProgramming(); + if (debugger) log(Log::LineType::Information, i18n("Stopped.")); + return true; +} + +bool Programmer::Manager::run() +{ + bool debugger = group().isDebugger(); + if ( !initProgramming(debugger) ) return false; + bool ok = (debugger ? ::Debugger::manager->run() : _programmer->run()); + setState(Idle); + return ok; +} + +bool Programmer::Manager::halt() +{ + bool debugger = group().isDebugger(); + bool ok = (debugger ? ::Debugger::manager->halt() : _programmer->stop()); + if (debugger) setState(Idle); + else { + endProgramming(); + log(Log::LineType::Information, i18n("Stopped.")); + } + return ok; +} + +void Programmer::Manager::stop() +{ + if (_programmer) _programmer->disconnectHardware(); +} + +bool Programmer::Manager::restart() +{ + bool ok; + if (group().isDebugger()) { + if ( _programmer==0 || _programmer->state()==::Programmer::NotConnected + || _programmer->state()==::Programmer::Stopped ) return step(); + if ( !initProgramming(true) ) return false; + ok = ::Debugger::manager->reset(); + log(Log::LineType::Information, i18n("Reset.<Translators: please translate the past form of the verb>", "Reset.")); + setState(Idle); + } else { + log(Log::LineType::Information, i18n("Restarting...")); + ok = _programmer->stop(); + Port::msleep(200); + if (ok) ok = _programmer->run(); + endProgramming(); + } + return ok; +} + +bool Programmer::Manager::step() +{ + if ( !initProgramming(true) ) return false; + bool ok = ::Debugger::manager->step(); + setState(Idle); + return ok; +} + +bool Programmer::Manager::isTargetSelfPowered() const +{ + if ( group().targetPowerMode()==TargetPowerModeFromConfig ) return readConfigEntry(Config::TargetSelfPowered).toBool(); + return ( group().targetPowerMode()==TargetSelfPowered ); +} diff --git a/src/progs/manager/prog_manager.h b/src/progs/manager/prog_manager.h new file mode 100644 index 0000000..11f7401 --- /dev/null +++ b/src/progs/manager/prog_manager.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 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 PROG_MANAGER_H +#define PROG_MANAGER_H + +#include <qobject.h> + +#include "common/global/log.h" +namespace Device { class Data; class Memory; class MemoryRange; } +namespace Port { class Description; } + +namespace Programmer +{ +class Base; +class Group; +class HardwareDescription; + +class Manager : public QObject, public Log::Base +{ +Q_OBJECT +public: + Manager(QObject *parent); + virtual ~Manager(); + ::Programmer::Base *programmer() { return _programmer; } + virtual void createProgrammer(const Device::Data *data) = 0; + bool initProgramming(bool debugging); + void endProgramming(); + void clear(); + void stop(); + bool program(const Device::Memory &memory, const Device::MemoryRange &range); + bool verify(const Device::Memory &memory, const Device::MemoryRange &range); + bool read(Device::Memory &memory, const Device::MemoryRange &range); + bool erase(const Device::MemoryRange &range); + bool blankCheck(const Device::MemoryRange &range); + bool setDevicePower(bool on); + enum State { Idle, Programming }; + virtual void setState(State state) = 0; + +public slots: + bool connectDevice(); + bool disconnectDevice(); + bool run(); + bool halt(); + bool restart(); + bool step(); + +signals: + void actionMessage(const QString &message); + void showProgress(bool show); + void setTotalProgress(uint steps); + void setProgress(uint steps); + +protected: + ::Programmer::Base *_programmer; + + virtual const Group &group() const = 0; + virtual bool internalInitProgramming(bool debugging); + virtual const Device::Data *device() const = 0; + virtual bool isTargetSelfPowered() const; + virtual void createProgrammer(const Device::Data *data, const HardwareDescription &hd); +}; + +extern Manager *manager; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/Makefile.am b/src/progs/picdem_bootloader/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/picdem_bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/picdem_bootloader/base/Makefile.am b/src/progs/picdem_bootloader/base/Makefile.am new file mode 100644 index 0000000..13a3add --- /dev/null +++ b/src/progs/picdem_bootloader/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicdembootloader.la +libpicdembootloader_la_SOURCES = picdem_bootloader_data.cpp picdem_bootloader.cpp picdem_bootloader_prog.cpp +libpicdembootloader_la_DEPENDENCIES = picdem_bootloader_data.cpp + +noinst_DATA = picdem_bootloader.xml +picdem_bootloader_data.cpp: ../xml/xml_picdem_bootloader_parser picdem_bootloader.xml + ../xml/xml_picdem_bootloader_parser +CLEANFILES = picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/base/base.pro b/src/progs/picdem_bootloader/base/base.pro new file mode 100644 index 0000000..8551799 --- /dev/null +++ b/src/progs/picdem_bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = picdem_bootloader +HEADERS += picdem_bootloader.h picdem_bootloader_prog.h picdem_bootloader_data.h +SOURCES += picdem_bootloader.cpp picdem_bootloader_prog.cpp picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.cpp b/src/progs/picdem_bootloader/base/picdem_bootloader.cpp new file mode 100644 index 0000000..f22eecb --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "picdem_bootloader.h" + +#include "progs/icd2/base/microchip.h" + +//----------------------------------------------------------------------------- +uint PicdemBootloader::Config::readVendorId() +{ + Config config; + return qMin(config.readUIntEntry("vendor_id", Microchip::VENDOR_ID), uint(0xFFFF)); +} +void PicdemBootloader::Config::writeVendorId(uint id) +{ + Config config; + config.writeEntry("vendor_id", id); +} + +uint PicdemBootloader::Config::readProductId() +{ + Config config; + return qMin(config.readUIntEntry("product_id", 0x000B), uint(0xFFFF)); +} +void PicdemBootloader::Config::writeProductId(uint id) +{ + Config config; + config.writeEntry("product_id", id); +} + +//----------------------------------------------------------------------------- +PicdemBootloader::Port::Port(Log::Base &log) + : Port::USB(log, Config::readVendorId(), Config::readProductId(), 1, 0) +{} + +bool PicdemBootloader::Port::receive(uint nb, QMemArray<uchar> &data) +{ + data.resize(nb); + if ( !read(0x81, (char *)data.data(), nb) ) return false; + log(Log::DebugLevel::Max, QString("received: \"%1\"").arg(toPrintable(data, PrintEscapeAll))); + return true; +} + +bool PicdemBootloader::Port::send(const QMemArray<uchar> &cmd) +{ + log(Log::DebugLevel::Extra, QString("send: \"%1\"").arg(toPrintable(cmd, PrintEscapeAll))); + return write(0x01, (const char *)cmd.data(), cmd.count()); +} + +bool PicdemBootloader::Port::sendAndReceive(QMemArray<uchar> &data, uint nb) +{ + if ( !send(data) ) return false; + return receive(nb, data); +} + +QMemArray<uchar> PicdemBootloader::Port::command(uchar instruction, uint address, uint len, uint nb) const +{ + QMemArray<uchar> cmd(5+nb); + cmd[0] = instruction; + cmd[1] = len; + cmd[2] = address & 0xFF; + cmd[3] = (address >> 8) & 0xFF; + cmd[4] = (address >> 16) & 0xFF; + return cmd; +} + +//----------------------------------------------------------------------------- +PicdemBootloader::Hardware::Hardware(::Programmer::Base &base) + : Bootloader::Hardware(base, new Port(base)) +{} + +bool PicdemBootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + QMemArray<uchar> cmd(5); + cmd.fill(0); + if ( !port().sendAndReceive(cmd, 4) ) return false; + VersionData version(cmd[3], cmd[2], 0); + log(Log::LineType::Information, i18n("Bootloader version %1 detected").arg(version.pretty())); + if ( version.majorNum()!=1 ) { + log(Log::LineType::Error, i18n("Only bootloader version 1.x is supported")); + return false; + } + return true; +} + +uchar PicdemBootloader::Hardware::writeInstruction(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 0x02; + case Pic::MemoryRangeType::Eeprom: return 0x05; + case Pic::MemoryRangeType::UserId: return 0x07; + default: Q_ASSERT(false); break; + } + return 0x00; +} + +bool PicdemBootloader::Hardware::write(Pic::MemoryRangeType type, const Device::Array &data) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + if ( type==Pic::MemoryRangeType::Code ) { // check that there is nothing in bootloader reserved area + for (uint i=0; i<data.count(); i++) { + if ( i>=0x400 ) continue; + if ( data[i]==device().mask(Pic::MemoryRangeType::Code) ) continue; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + log(Log::LineType::Warning, " " + i18n("Code is present in bootloader reserved area (at address %1). It will be ignored.").arg(toHexLabel(address, device().nbCharsAddress()))); + break; + } + } + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + uint offset = (type==Pic::MemoryRangeType::Code ? 0x0800 : 0x00); + for (; offset<nbBytes; offset+=16) { + QMemArray<uchar> cmd = port().command(0x02, device().range(type).start.toUInt() + offset, 16, 16); + for (uint k=0; k<16; k += nbBytesWord) { + uint index = (offset + k) / nbBytesWord; + cmd[5 + k] = data[index].byte(0); + if ( nbBytesWord==2 ) cmd[5 + k+1] = data[index].byte(1); + } + if ( !port().sendAndReceive(cmd, 1) ) return false; + } + return true; +} + +uchar PicdemBootloader::Hardware::readInstruction(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 0x01; + case Pic::MemoryRangeType::Eeprom: return 0x04; + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::UserId: return 0x06; + default: Q_ASSERT(false); break; + } + return 0x00; +} + +bool PicdemBootloader::Hardware::read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + Device::Array varray; + if (vdata) varray = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type); + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + uint nb = QMIN(uint(16), nbBytes); + for (uint offset=0; offset<nbBytes; offset+=16) { + QMemArray<uchar> cmd = port().command(readInstruction(type), device().range(type).start.toUInt() + offset, nb, 0); + if ( !port().sendAndReceive(cmd, 5+nb) ) return false; + for (uint k=0; k<nb; k += nbBytesWord) { + uint index = (offset + k) / nbBytesWord; + data[index]= cmd[5 + k] & 0xFF; + if ( nbBytesWord==2 ) data[index] |= (cmd[5 + k+1] << 8); + if ( vdata && index>=0x0800 && data[index]!=varray[index] ) { + log(Log::LineType::Error, i18n("Device memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).") + .arg(QString(toHex(index/2, device().nbCharsAddress()))) + .arg(QString(toHex(data[index], device().nbCharsWord(type)))) + .arg(QString(toHex(varray[index], device().nbCharsWord(type))))); + return false; + } + } + } + return true; +} + +bool PicdemBootloader::Hardware::erase(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) { + Pic::Memory memory(device()); + Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Eeprom); + return write(Pic::MemoryRangeType::Eeprom, data); + } + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + for (uint offset=0x0800; offset<nbBytes; offset+=64) { + QMemArray<uchar> cmd = port().command(0x03, device().range(type).start.toUInt() + offset, 1, 0); + if ( !port().sendAndReceive(cmd, 1) ) return false; + } + return true; +} diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.h b/src/progs/picdem_bootloader/base/picdem_bootloader.h new file mode 100644 index 0000000..3081382 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICDEM_BOOTLOADER_H +#define PICDEM_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "common/port/usb_port.h" + +namespace PicdemBootloader +{ +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + static uint readVendorId(); + static void writeVendorId(uint id); + static uint readProductId(); + static void writeProductId(uint id); + +private: + Config() : GenericConfig("picdem_bootloader") {} +}; + +//----------------------------------------------------------------------------- +class Port : public ::Port::USB +{ +public: + Port(Log::Base &base); + bool receive(uint nb, QMemArray<uchar> &array); + bool send(const QMemArray<uchar> &array); + bool sendAndReceive(QMemArray<uchar> &data, uint nb); + QMemArray<uchar> command(uchar instruction, uint address, uint len, uint nb) const; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base); + Port &port() { return static_cast<Port &>(*_port); } + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool erase(Pic::MemoryRangeType type); + virtual bool internalConnectHardware(); + +private: + static uchar readInstruction(Pic::MemoryRangeType type); + static uchar writeInstruction(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Eeprom || type==Pic::MemoryRangeType::Code ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Eeprom || type==Pic::MemoryRangeType::Code ); } + virtual bool doEraseRange(Pic::MemoryRangeType type) { return static_cast<Hardware &>(hardware()).erase(type); } + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code) && doEraseRange(Pic::MemoryRangeType::Eeprom); } +}; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.xml b/src/progs/picdem_bootloader/base/picdem_bootloader.xml new file mode 100644 index 0000000..1cbfecb --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.xml @@ -0,0 +1,16 @@ +<!-- ************************************************************************* --> +<!-- * Copyright (C) 2007 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="picdem_bootloader"> + <device name="18F2455" family="generic" id="0x00" /> + <device name="18F2550" family="generic" id="0x00" /> + <device name="18F4455" family="generic" id="0x00" /> + <device name="18F4550" family="generic" id="0x00" /> +</type> diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_data.h b/src/progs/picdem_bootloader/base/picdem_bootloader_data.h new file mode 100644 index 0000000..bf2a40f --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_data.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICDEM_BOOTLOADER_DATA_H +#define PICDEM_BOOTLOADER_DATA_H + +namespace PicdemBootloader +{ + struct Data {}; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp new file mode 100644 index 0000000..72fc384 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "picdem_bootloader_prog.h" + +//----------------------------------------------------------------------------- +PicdemBootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "picdem_bootloader_programmer_base") +{} diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h new file mode 100644 index 0000000..698d612 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICDEM_BOOTLOADER_PROG_H +#define PICDEM_BOOTLOADER_PROG_H + +#include "progs/bootloader/base/bootloader_prog.h" +#include "picdem_bootloader.h" + +namespace PicdemBootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "picdem_bootloader"; } + virtual QString label() const { return i18n("Picdem Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::USB; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const { return new Hardware(base); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/gui/Makefile.am b/src/progs/picdem_bootloader/gui/Makefile.am new file mode 100644 index 0000000..57d10bb --- /dev/null +++ b/src/progs/picdem_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicdembootloaderui.la +libpicdembootloaderui_la_LDFLAGS = $(all_libraries) +libpicdembootloaderui_la_SOURCES = picdem_bootloader_ui.cpp diff --git a/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp new file mode 100644 index 0000000..c958249 --- /dev/null +++ b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "picdem_bootloader_ui.h" + +#include "progs/picdem_bootloader/base/picdem_bootloader.h" + +//----------------------------------------------------------------------------- +PicdemBootloader::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + + QLabel *label = new QLabel(i18n("USB Vendor Id:"), this); + addWidget(label, row,row, 0,0); + _vendorId = new HexWordEditor(4, this); + addWidget(_vendorId, row,row, 1,1); + row++; + + label = new QLabel(i18n("USB Product Id:"), this); + addWidget(label, row,row, 0,0); + _productId = new HexWordEditor(4, this); + addWidget(_productId, row,row, 1,1); + row++; +} + +void PicdemBootloader::ConfigWidget::saveConfig() +{ + Config::writeVendorId(_vendorId->value().toUInt()); + Config::writeProductId(_productId->value().toUInt()); +} + +void PicdemBootloader::ConfigWidget::loadConfig() +{ + _vendorId->setValue(Config::readVendorId()); + _productId->setValue(Config::readProductId()); +} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *PicdemBootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} diff --git a/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h new file mode 100644 index 0000000..50777af --- /dev/null +++ b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICDEM_BOOTLOADER_UI_H +#define PICDEM_BOOTLOADER_UI_H + +#include "progs/bootloader/gui/bootloader_ui.h" + +namespace PicdemBootloader +{ +//---------------------------------------------------------------------------- +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual void loadConfig(); + virtual void saveConfig(); + +private: + HexWordEditor *_vendorId, *_productId; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/picdem_bootloader.pro b/src/progs/picdem_bootloader/picdem_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/picdem_bootloader/picdem_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/picdem_bootloader/xml/Makefile.am b/src/progs/picdem_bootloader/xml/Makefile.am new file mode 100644 index 0000000..5ed38e6 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_picdem_bootloader_parser +xml_picdem_bootloader_parser_SOURCES = xml_picdem_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_picdem_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_picdem_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/picdem_bootloader/xml/xml.pro b/src/progs/picdem_bootloader/xml/xml.pro new file mode 100644 index 0000000..4e2eb15 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_picdem_bootloader_parser +SOURCES += xml_picdem_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_picdem_bootloader_parser +unix:QMAKE_CLEAN += ../base/picdem_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_picdem_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp b/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp new file mode 100644 index 0000000..745b6a0 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "xml_to_data/prog_xml_to_data.h" + +#include "progs/picdem_bootloader/base/picdem_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace PicdemBootloader +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("picdem_bootloader", "PicdemBootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); +}; + +void PicdemBootloader::XmlToData::parseData(QDomElement, Data &) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast<const Pic::Data *>(ddata); + if ( !pdata->hasFeature(Pic::Feature::USB) ) qFatal("device does not have USB"); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(PicdemBootloader::XmlToData) diff --git a/src/progs/pickit1/Makefile.am b/src/progs/pickit1/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/pickit1/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/pickit1/base/Makefile.am b/src/progs/pickit1/base/Makefile.am new file mode 100644 index 0000000..74d56f0 --- /dev/null +++ b/src/progs/pickit1/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit1.la +libpickit1_la_SOURCES = pickit1.cpp pickit1_prog.cpp pickit1_data.cpp +libpickit1_la_DEPENDENCIES = pickit1_data.cpp + +noinst_DATA = pickit1.xml +pickit1_data.cpp: ../xml/xml_pickit1_parser pickit1.xml + ../xml/xml_pickit1_parser +CLEANFILES = pickit1_data.cpp diff --git a/src/progs/pickit1/base/base.pro b/src/progs/pickit1/base/base.pro new file mode 100644 index 0000000..bdd257b --- /dev/null +++ b/src/progs/pickit1/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit1 +HEADERS += pickit1.h pickit1_prog.h pickit1_data.h +SOURCES += pickit1.cpp pickit1_prog.cpp pickit1_data.cpp diff --git a/src/progs/pickit1/base/pickit1.cpp b/src/progs/pickit1/base/pickit1.cpp new file mode 100644 index 0000000..c5ab021 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * 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 "pickit1.h" + +bool Pickit1::Baseline::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x08; // Begin Programming externally timed + cmd[1] = 0x0E; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit1::Baseline::incrementPC(uint nb) +{ + if ( (nb & 0xFF)!=0 ) return Pickit::Baseline::incrementPC(nb); + // work around bugs in firmware + Array cmd; + uint high = (nb >> 8) & 0xFF; + log(Log::DebugLevel::Extra, QString("work around bug in firmware (nb_inc=%1 high=%2)") + .arg(toHexLabel(nb, 4)).arg(toHexLabel(high, 2))); + if ( high==1 ) { + cmd[0] = 'I'; + cmd[1] = 0x40; + cmd[2] = 0x00; + cmd[3] = 'I'; + cmd[4] = 0xC0; + cmd[5] = 0x00; + } else { + cmd[0] = 'I'; + cmd[1] = 0x00; + cmd[2] = high-1; + } + return hardware().port().command(cmd); +} + +//---------------------------------------------------------------------------- +bool Pickit1::P16F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x18; // Begin Programming externally timed + cmd[1] = 0x0A; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit1::P16F716::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x18; // Begin Programming externally timed + cmd[1] = 0x0E; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} diff --git a/src/progs/pickit1/base/pickit1.h b/src/progs/pickit1/base/pickit1.h new file mode 100644 index 0000000..75e1d82 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * 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 PICKIT1_H +#define PICKIT1_H + +#include "progs/pickit2/base/pickit.h" +#include "pickit1_data.h" + +namespace Pickit1 +{ +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(8, 'Z', PrintAlphaNum) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit::USBPort +{ +public: + USBPort(Log::Base &log) : Pickit::USBPort(0x0032, log) {} + virtual Pickit::Array array() const { return Array(); } + +private: + virtual uint readEndPoint() const { return 0x81; } + virtual uint writeEndPoint() const { return 0x01; } +}; + +//----------------------------------------------------------------------------- +class Hardware : public Pickit::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Pickit::Hardware(base, new USBPort(base)) {} +}; + +//---------------------------------------------------------------------------- +class Baseline : public Pickit::Baseline +{ +public: + Baseline(::Programmer::Base &base) : Pickit::Baseline(base) {} + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual bool init(); + virtual uint nbWrites(Pic::MemoryRangeType) const { return 1; } + virtual bool incrementPC(uint nb); +}; + +//---------------------------------------------------------------------------- +class P16F : public Pickit::P16F +{ +public: + P16F(::Programmer::Base &base) : Pickit::P16F(base) {} + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual bool init(); + virtual uint nbWrites(Pic::MemoryRangeType) const { return 1; } +}; + +class P16F716 : public P16F +{ +public: + P16F716(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/base/pickit1.xml b/src/progs/pickit1/base/pickit1.xml new file mode 100644 index 0000000..899b504 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.xml @@ -0,0 +1,52 @@ +<!-- ************************************************************************* --> +<!-- * 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="pickit1"> + <device name="10F200" family="Baseline" entry="O" support_type="tested" /> + <device name="10F202" family="Baseline" entry="O" support_type="tested" /> + <device name="10F204" family="Baseline" entry="O" support_type="tested" /> + <device name="10F206" family="Baseline" entry="O" support_type="tested" /> + <device name="10F220" family="Baseline" entry="O" /> + <device name="10F222" family="Baseline" entry="O" /> + <device name="12F508" family="Baseline" entry="O" support_type="tested" /> + <device name="12F509" family="Baseline" entry="O" support_type="tested" /> + <device name="12F510" family="Baseline" entry="O" support_type="tested" /> + <device name="16F505" family="Baseline" entry="O" /> + <device name="16F506" family="Baseline" entry="O" /> + <device name="16F54" family="Baseline" entry="O" /> + <device name="16F57" family="Baseline" entry="O" /> + <device name="16F59" family="Baseline" entry="O" /> + + <device name="12F629" family="P16F" entry="P" regen="true" support_type="tested" /> + <device name="12F635" family="P16F" entry="P" support_type="tested" /> + <device name="12F675" family="P16F" entry="P" regen="true" support_type="tested" /> + <device name="12F683" family="P16F" entry="P" support_type="tested" /> + <device name="16F627A" family="P16F" entry="P" /> + <device name="16F628A" family="P16F" entry="P" /> + <device name="16F630" family="P16F" entry="P" regen="true" support_type="tested" /> + <device name="16F636" family="P16F" entry="P" support_type="tested" /> + <device name="16F639" family="P16F" entry="P" support_type="tested" /> + <device name="16F648A" family="P16F" entry="P" /> + <device name="16F676" family="P16F" entry="P" regen="true" support_type="tested" /> + <device name="16F684" family="P16F" entry="P" support_type="tested" /> + <device name="16F685" family="P16F" entry="P" /> + <device name="16F687" family="P16F" entry="P" /> + <device name="16F688" family="P16F" entry="P" support_type="tested" /> + <device name="16F689" family="P16F" entry="P" /> + <device name="16F690" family="P16F" entry="P" /> + <device name="16F716" family="P16F716" entry="O" /> + <device name="16F785" family="P16F" entry="P" /> + <device name="16F877A" family="P16F" entry="O" /> + <device name="16F913" family="P16F" entry="O" /> + <device name="16F914" family="P16F" entry="O" /> + <device name="16F916" family="P16F" entry="O" /> + <device name="16F917" family="P16F" entry="O" /> + <device name="16F946" family="P16F" entry="O" /> +</type> diff --git a/src/progs/pickit1/base/pickit1_data.h b/src/progs/pickit1/base/pickit1_data.h new file mode 100644 index 0000000..767fc4b --- /dev/null +++ b/src/progs/pickit1/base/pickit1_data.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * 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 PICKIT1_DATA_H +#define PICKIT1_DATA_H + +#include <qstring.h> + +namespace Pickit1 +{ + struct Data { + char entryMode; + bool regenerateOsccal; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit1/base/pickit1_prog.cpp b/src/progs/pickit1/base/pickit1_prog.cpp new file mode 100644 index 0000000..b43a19c --- /dev/null +++ b/src/progs/pickit1/base/pickit1_prog.cpp @@ -0,0 +1,28 @@ +/*************************************************************************** + * 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 "pickit1_prog.h" + +#include "pickit1.h" + +//---------------------------------------------------------------------------- +bool Pickit1::Base::deviceHasOsccalRegeneration() const +{ + return data(device()->name()).regenerateOsccal; +} + +bool Pickit1::Base::setTarget() +{ + return static_cast<Pickit::DeviceSpecific *>(_specific)->init(); +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit1::Group::createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} diff --git a/src/progs/pickit1/base/pickit1_prog.h b/src/progs/pickit1/base/pickit1_prog.h new file mode 100644 index 0000000..c0763b4 --- /dev/null +++ b/src/progs/pickit1/base/pickit1_prog.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * 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 PICKIT1_PROG_H +#define PICKIT1_PROG_H + +#include "progs/pickit2/base/pickit_prog.h" + +namespace Pickit1 +{ +//---------------------------------------------------------------------------- +class Base : public Pickit::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) : Pickit::Base(group, data) {} + virtual bool deviceHasOsccalRegeneration() const; + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + virtual bool setTarget(); + +private: + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType) const { return VersionData(2, 0, 0); } +}; + +//---------------------------------------------------------------------------- +class Group : public Pickit::Group +{ +public: + virtual QString name() const { return "pickit1"; } + virtual QString label() const { return i18n("PICkit1"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit1::Base(*this, static_cast<const Pic::Data *>(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/gui/Makefile.am b/src/progs/pickit1/gui/Makefile.am new file mode 100644 index 0000000..239184b --- /dev/null +++ b/src/progs/pickit1/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit1ui.la +libpickit1ui_la_SOURCES = pickit1_group_ui.cpp +libpickit1ui_la_LDFLAGS = $(all_libraries) diff --git a/src/progs/pickit1/gui/pickit1_group_ui.cpp b/src/progs/pickit1/gui/pickit1_group_ui.cpp new file mode 100644 index 0000000..2c862fb --- /dev/null +++ b/src/progs/pickit1/gui/pickit1_group_ui.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * 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 "pickit1_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/pickit2/gui/pickit2_group_ui.h" +#include "progs/pickit1/base/pickit1_prog.h" + +::Programmer::ConfigWidget *Pickit1::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit1::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new Pickit::AdvancedDialog(static_cast<Base &>(base), parent, "pickit1_advanced_dialog"); +} diff --git a/src/progs/pickit1/gui/pickit1_group_ui.h b/src/progs/pickit1/gui/pickit1_group_ui.h new file mode 100644 index 0000000..5fb8ad6 --- /dev/null +++ b/src/progs/pickit1/gui/pickit1_group_ui.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * 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 PICKIT1_GROUP_UI_H +#define PICKIT1_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Pickit1 +{ + +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/pickit1.pro b/src/progs/pickit1/pickit1.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit1/pickit1.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit1/xml/Makefile.am b/src/progs/pickit1/xml/Makefile.am new file mode 100644 index 0000000..f0cc91a --- /dev/null +++ b/src/progs/pickit1/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit1_parser +xml_pickit1_parser_SOURCES = xml_pickit1_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit1_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit1_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit1/xml/xml.pro b/src/progs/pickit1/xml/xml.pro new file mode 100644 index 0000000..e368c49 --- /dev/null +++ b/src/progs/pickit1/xml/xml.pro @@ -0,0 +1,18 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit1_parser +SOURCES += xml_pickit1_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit1_parser +unix:QMAKE_CLEAN += ../base/pickit1_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit1_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit1_data.cpp + diff --git a/src/progs/pickit1/xml/xml_pickit1_parser.cpp b/src/progs/pickit1/xml/xml_pickit1_parser.cpp new file mode 100644 index 0000000..e5d1b78 --- /dev/null +++ b/src/progs/pickit1/xml/xml_pickit1_parser.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "progs/pickit1/base/pickit1_data.h" + +namespace Pickit1 +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("pickit1", "Pickit1") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Pickit1::XmlToData::parseData(QDomElement element, Data &data) +{ + QString s = element.attribute("entry"); + if ( s.length()!=1 || (s[0]!='O' && s[0]!='P') ) qFatal("Invalid or missing entry mode"); + data.entryMode = s[0].latin1(); + s = element.attribute("regen"); + if ( s.isEmpty() || s=="false" ) data.regenerateOsccal = false; + else if ( s=="true" ) data.regenerateOsccal = true; + else qFatal("Invalid regen value"); +} + +void Pickit1::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << "'" << data.entryMode << "', " << (data.regenerateOsccal ? "true" : "false"); +} + +void Pickit1::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData<Data>::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Group::createDeviceSpecific(Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast< ::Pickit1::Base &>(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i<uint(families().count()); i++) { + s << " case " + QString::number(i) + ": return new " + families()[i] + "(base);" << endl; + } + s << " }" << endl; + s << " Q_ASSERT(false);" << endl; + s << " return 0;" << endl; + s << "}" << endl; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Pickit1::XmlToData) diff --git a/src/progs/pickit2/Makefile.am b/src/progs/pickit2/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/pickit2/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/pickit2/base/Makefile.am b/src/progs/pickit2/base/Makefile.am new file mode 100644 index 0000000..a436012 --- /dev/null +++ b/src/progs/pickit2/base/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2.la +libpickit2_la_SOURCES = pickit2_data.cpp pickit.cpp pickit_prog.cpp \ + pickit2.cpp pickit2_prog.cpp +libpickit2_la_DEPENDENCIES = pickit2_data.cpp + +noinst_DATA = pickit2.xml +pickit2_data.cpp: ../xml/xml_pickit2_parser pickit2.xml + ../xml/xml_pickit2_parser +CLEANFILES = pickit2_data.cpp diff --git a/src/progs/pickit2/base/base.pro b/src/progs/pickit2/base/base.pro new file mode 100644 index 0000000..3a229e3 --- /dev/null +++ b/src/progs/pickit2/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit2 +HEADERS += pickit.h pickit_prog.h pickit2.h pickit2_data.h pickit2_prog.h +SOURCES += pickit.cpp pickit_prog.cpp pickit2.cpp pickit2_data.cpp pickit2_prog.cpp diff --git a/src/progs/pickit2/base/pickit.cpp b/src/progs/pickit2/base/pickit.cpp new file mode 100644 index 0000000..7da2d18 --- /dev/null +++ b/src/progs/pickit2/base/pickit.cpp @@ -0,0 +1,337 @@ +/*************************************************************************** + * 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 "pickit.h" + +#include "devices/base/device_group.h" +#include "progs/base/prog_group.h" + +//----------------------------------------------------------------------------- +Pickit::Array::Array(uint length, uchar fillChar, PrintMode mode) + : _fillChar(fillChar), _mode(mode), _data(length) +{ + _data.fill(fillChar); +} + +QString Pickit::Array::pretty() const +{ + int end = _data.count() - 1; + for (; end>=0; end--) + if ( _data[end]!=_fillChar ) break; + QString s; + for (int i=0; i<=end; i++) s += toPrintable(_data[i], _mode); + return s; +} + +//----------------------------------------------------------------------------- +Pickit::USBPort::USBPort(uint deviceId, Log::Base &log) + : Port::USB(log, Microchip::VENDOR_ID, deviceId, CONFIG_VENDOR, 0) +{} + +bool Pickit::USBPort::command(uchar c) +{ + Array a = array(); + a._data[0] = c; + return command(a); +} + +bool Pickit::USBPort::command(const char *s) +{ + Array a = array(); + if (s) { + Q_ASSERT( strlen(s)<=a.length() ); + for (uint i=0; i<strlen(s); i++) a._data[i] = s[i]; + } + return command(a); +} + +bool Pickit::USBPort::command(const Array &cmd) +{ + log(Log::DebugLevel::Extra, QString("send command: \"%1\"").arg(cmd.pretty())); + return write(writeEndPoint(), (const char *)cmd._data.data(), cmd.length()); +} + +bool Pickit::USBPort::receive(Pickit::Array &array) +{ + if ( !read(readEndPoint(), (char *)array._data.data(), array.length()) ) return false; + log(Log::DebugLevel::Max, QString("received: \"%1\"").arg(array.pretty())); + return true; +} + +bool Pickit::USBPort::getMode(VersionData &version, ::Programmer::Mode &mode) +{ + if ( !command('v') ) return false; + Array a = array(); + if ( !receive(a) ) return false; + if ( a[5]=='B' ) { + version = VersionData(a[6], a[7], 0); + mode = ::Programmer::BootloadMode; + } else { + version = VersionData(a[0], a[1], a[2]); + mode = ::Programmer::NormalMode; + } + return true; +} + +bool Pickit::USBPort::receiveWords(uint nbBytesWord, uint nbRead, QValueVector<uint> &words, uint offset) +{ + log(Log::DebugLevel::Max, QString("receive words nbBytesWord=%1 nbRead=%2 offset=%3").arg(nbBytesWord).arg(nbRead).arg(offset)); + Array a = array(); + QMemArray<uchar> data(nbRead*a.length()); + uint l = 0; + for (uint i=0; i<nbRead; i++) { + if ( !receive(a) ) return false; + for (uint k=offset; k<a.length(); k++) { + data[l] = a[k]; + l++; + } + } + words.resize(data.count()/nbBytesWord); + for (uint i=0; i<uint(words.count()); i++) { + words[i] = 0; + for (uint k=0; k<nbBytesWord; k++) words[i] |= data[nbBytesWord*i + k] << (8*k); + } + return true; +} + +//----------------------------------------------------------------------------- +Pickit::Hardware::Hardware(::Programmer::Base &base, USBPort *port) + : ::Programmer::PicHardware(base, port, QString::null) +{} + +bool Pickit::Hardware::internalConnectHardware() +{ + return port().open(); +} + +bool Pickit::Hardware::setTargetPower(uint v) +{ + Array cmd = port().array(); + cmd[0] = 'V'; + cmd[1] = v; + return port().command(cmd); +} + +bool Pickit::Hardware::writeWords(uint max, char c, uint nbBytesWord, + uint &i, const Device::Array &data) +{ + Q_ASSERT( i<data.count() ); + Q_ASSERT( nbBytesWord==1 || nbBytesWord==2 ); + Array cmd = port().array(); + uint n = (nbBytesWord==1 ? 2 : 3); + Q_ASSERT( n*max<=cmd.length() ); + for (uint k=0; k<max; k++) { + cmd[n*k] = c; + cmd[n*k+1] = data[i].byte(0); + if ( nbBytesWord==2 ) cmd[n*k+2] = data[i].byte(1); + i++; + if ( i>=data.count() ) break; + } + return port().command(cmd); +} + +bool Pickit::Hardware::regenerateOsccal(BitValue &newValue) +{ + if ( !setTargetPower(Osc2_5kHz) ) return false; + if ( !setTargetPower(PowerOn + Osc2_5kHz) ) return false; + Port::usleep(400000); // 400 ms + if ( !setTargetPower(PowerOff) ) return false; + Pickit::Array cmd = port().array(); + cmd[0] = 'P'; + cmd[1] = 'I'; + cmd[2] = 120; + cmd[3] = 0; + cmd[4] = 'r'; + cmd[5] = 'p'; + if ( !port().command(cmd) ) return false; + QValueVector<uint> words; + if ( !port().receiveWords(1, 1, words) ) return false; + newValue = words[7] | 0x3400; + return true; +} + +//---------------------------------------------------------------------------- +bool Pickit::DeviceSpecific::setPowerOn() +{ + return hardware().port().command(entryMode()); +} + +bool Pickit::DeviceSpecific::setPowerOff() +{ + return hardware().port().command('p'); +} + +bool Pickit::DeviceSpecific::setTargetPowerOn(bool on) +{ + return hardware().setTargetPower(on ? PowerOn : PowerOff); +} + +//---------------------------------------------------------------------------- +bool Pickit::BMDeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + gotoMemory(type); + QValueVector<uint> words; + switch (type.type()) { + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::DeviceId: + for (uint i=0; i<data.count();) { + if ( !hardware().port().command('R') ) return false; + if ( !hardware().port().receiveWords(2, 1, words) ) return false; + for (uint k=0; k<uint(words.count()); k++) { + data[i] = words[k]; + if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false; + i++; + if ( i>=data.count() ) break; + } + } + break; + case Pic::MemoryRangeType::Eeprom: + for (uint i=0; i<data.count();) { + if ( !hardware().port().command('r') ) return false; // #### not sure this is correct for Pickit1: "rrrrrrrr" used by usb_pickit + if ( !hardware().port().receiveWords(1, 1, words) ) return false; + for (uint k=0; k<uint(words.count()); k++) { + data[i] = words[k]; + if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false; + i++; + if ( i>=data.count() ) break; + } + } + break; + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(data.count()); + return true; +} + +bool Pickit::BMDeviceSpecific::incrementPC(uint nb) +{ + Pickit::Array cmd = hardware().port().array(); + cmd[0] = 'I'; + cmd[1] = nb & 0xFF; + cmd[2] = (nb >> 8) & 0xFF; + return hardware().port().command(cmd); +} + +bool Pickit::BMDeviceSpecific::doEraseRange(Pic::MemoryRangeType type) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + return hardware().port().command('E'); +} + +bool Pickit::BMDeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + // #### TODO: speed optimize... + Q_UNUSED(force); + gotoMemory(type); + uint nb = nbWrites(type); + switch (type.type()) { + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::UserId: + for (uint i=0; i<data.count(); ) + hardware().writeWords(nb, writeCode(), 2, i, data); + break; + case Pic::MemoryRangeType::Eeprom: + for (uint i=0; i<data.count(); ) + hardware().writeWords(nb, writeData(), 1, i, data); + break; + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(data.count()); + return true; +} + +//---------------------------------------------------------------------------- +bool Pickit::Baseline::gotoMemory(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::CalBackup: return incrementPC(1+device().range(type).start.toUInt()); + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//---------------------------------------------------------------------------- +bool Pickit::P16F::gotoMemory(Pic::MemoryRangeType type) +{ + Pickit::Array cmd = hardware().port().array(); + cmd[0] = 'C'; + switch (type.type()) { + case Pic::MemoryRangeType::Code: return true; + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::UserId: return hardware().port().command(cmd); + case Pic::MemoryRangeType::DeviceId: + cmd[1] = 'I'; + cmd[2] = 0x06; + cmd[3] = 0x00; + return hardware().port().command(cmd); + case Pic::MemoryRangeType::Config: + cmd[1] = 'I'; + cmd[2] = 0x07; + cmd[3] = 0x00; + return hardware().port().command(cmd); + case Pic::MemoryRangeType::Cal: + if ( device().range(type).start==device().range(Pic::MemoryRangeType::Code).end+1 ) + return incrementPC(device().range(type).start.toUInt()); + cmd[1] = 'I'; + cmd[2] = 0x08; + cmd[3] = 0x00; + return hardware().port().command(cmd); + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +bool Pickit::P16F::doErase(bool) +{ + Pickit::Array cmd = hardware().port().array(); + cmd[0] = 'C'; + cmd[1] = writeCode(); + cmd[2] = 0xFF; + cmd[3] = 0x3F; + cmd[4] = 'E'; + cmd[5] = 'e'; + return hardware().port().command(cmd); +} + +bool Pickit::P16F::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return hardware().port().command('e'); + return BMDeviceSpecific::doEraseRange(type); +} diff --git a/src/progs/pickit2/base/pickit.h b/src/progs/pickit2/base/pickit.h new file mode 100644 index 0000000..741ed61 --- /dev/null +++ b/src/progs/pickit2/base/pickit.h @@ -0,0 +1,137 @@ +/*************************************************************************** + * 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 PICKIT_H +#define PICKIT_H + +#include "progs/icd2/base/microchip.h" +#include "common/port/usb_port.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/pic/prog/pic_prog.h" + +namespace Pickit +{ +enum PowerType { PowerOff = 0, PowerOn = 1, Osc2_5kHz = 2 }; + +//----------------------------------------------------------------------------- +class Array +{ +public: + uint length() const { return _data.count(); } + QString pretty() const; + uchar &operator[](uint i) { return _data[i]; } + uchar operator[](uint i) const { return _data[i]; } + +protected: + Array(uint length, uchar fillChar, PrintMode mode); + +private: + uchar _fillChar; + PrintMode _mode; + QMemArray<uchar> _data; + + friend class USBPort; +}; + +//----------------------------------------------------------------------------- +class USBPort : public Port::USB +{ +public: + USBPort(uint deviceId, Log::Base &manager); + virtual Array array() const = 0; + bool command(const Array &cmd); + bool command(uchar c); + bool command(const char *s); + bool receive(Array &data); + bool getMode(VersionData &version, ::Programmer::Mode &mode); + bool receiveWords(uint nbBytesWord, uint nbRead, QValueVector<uint> &data, uint offset = 0); + +protected: + virtual uint writeEndPoint() const = 0; + virtual uint readEndPoint() const = 0; + +private: + virtual uint timeout(uint) const { return 10000; } // 10s + enum { CONFIG_HID = 1, // use HID for pickit configuration + CONFIG_VENDOR = 2 // vendor specific configuration + }; +}; + +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, USBPort *port); + bool setTargetPower(uint value); + USBPort &port() { return static_cast<USBPort &>(*_port); } + const USBPort &port() const { return static_cast<USBPort &>(*_port); } + bool writeWords(uint max, char c, uint nbBytesWord, + uint &i, const Device::Array &data); + bool regenerateOsccal(BitValue &newValue); + +protected: + virtual bool internalConnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + virtual bool init() = 0; + virtual bool setPowerOn(); + virtual bool setPowerOff(); + virtual bool setTargetPowerOn(bool on); + virtual char entryMode() const = 0; +}; + +//----------------------------------------------------------------------------- +class BMDeviceSpecific : public DeviceSpecific +{ +public: + BMDeviceSpecific(::Programmer::Base &base) : DeviceSpecific(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type) = 0; + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool incrementPC(uint nb); + virtual uint nbWrites(Pic::MemoryRangeType type) const = 0; + virtual char writeCode() const = 0; + virtual char writeData() const = 0; + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool doEraseRange(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class Baseline : public BMDeviceSpecific +{ +public: + Baseline(::Programmer::Base &base) : BMDeviceSpecific(base) {} + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code); } + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual char writeCode() const { return 'w'; } + virtual char writeData() const { return 'D'; } +}; + +class P16F : public BMDeviceSpecific +{ +public: + P16F(::Programmer::Base &base) : BMDeviceSpecific(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); + virtual char writeCode() const { return 'W'; } + virtual char writeData() const { return 'D'; } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2.cpp b/src/progs/pickit2/base/pickit2.cpp new file mode 100644 index 0000000..6458fa2 --- /dev/null +++ b/src/progs/pickit2/base/pickit2.cpp @@ -0,0 +1,447 @@ +/*************************************************************************** + * 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 "pickit2.h" + +#include "common/global/global.h" +#include "devices/list/device_list.h" +#include "common/port/port.h" + +//----------------------------------------------------------------------------- +void Pickit2::USBPort::fillCommand(Pickit::Array &cmd, uchar command, uint nbBytes, + uint address, uint i, bool longAddress) const +{ + cmd[i] = command; + cmd[i+1] = nbBytes; + cmd[i+2] = address & 0xFF; + cmd[i+3] = (address >> 8) & 0xFF; + if (longAddress) cmd[i+4] = (address >> 16) & 0xFF; +} + +Pickit::Array Pickit2::USBPort::createCommand(uchar c, uint nbBytes, uint address, bool longAddress) const +{ + Array cmd; + fillCommand(cmd, c, nbBytes, address, 0, longAddress); + return cmd; +} + +bool Pickit2::USBPort::readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor) +{ + const Pic::Data *device = static_cast<const Pic::Data *>(Device::lister().data("18F2455")); + log(Log::DebugLevel::Normal, " Read pickit2 firmware"); + for (uint i=0; i<data.count(); i+=16) { // 2 bytes/word and 32 bytes/command max + uint start = 0; + for (; start<16; start++) if ( data[i + start].isInitialized() ) break; + if ( start==16 ) continue; + uint end = 15; + for (; end>start; end--) if ( data[i + end].isInitialized() ) break; + uint nb = end - start + 1; + Pickit::Array cmd = createCommand(1, 2*nb, 2*i); + if ( !command(cmd) ) return false; + QValueVector<uint> read; + if ( !receiveWords(1, 1, read) ) return false; + for (uint k=0; k<nb; k++) { + uint index = i + start + k; + data[index]= read[5 + 2*k] & 0xFF | (read[6 + 2*k] << 8); + if ( vdata && index>=0x1000 && index<0x3FF0 && data[index]!=(*vdata)[index] ) { + log(Log::LineType::Error, i18n("Firmware memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).") + .arg(QString(toHex(index/2, device->nbCharsAddress()))) + .arg(QString(toHex(data[index], device->nbCharsWord(Pic::MemoryRangeType::Code)))) + .arg(QString(toHex((*vdata)[index], device->nbCharsWord(Pic::MemoryRangeType::Code))))); + return false; + } + } + } + monitor.addTaskProgress(data.count()); + return true; +} + +bool Pickit2::USBPort::eraseFirmwareCodeMemory() +{ + log(Log::DebugLevel::Normal, " Erase pickit2 firmware"); + Pickit::Array cmd = createCommand(3, 0xC0, 0x2000); + if ( !command(cmd) ) return false; // erase 0x2000-0x4FFF + Port::usleep(1000000); + cmd = createCommand(3, 0xC0, 0x5000); + if ( !command(cmd) ) return false; // erase 0x5000-0x7FFF + Port::usleep(1000000); + return true; +} + +bool Pickit2::USBPort::writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor) +{ + log(Log::DebugLevel::Normal, " Write pickit2 firmware"); + for (uint i=0x1000; i<data.count(); i+=16) { // 2 bytes/word and 32 bytes/command max + uint start = 0; + for (; start<16; start++) if ( data[i + start].isInitialized() ) break; + if ( start==16 ) continue; + uint end = 15; + for (; end>start; end--) if ( data[i + end].isInitialized() ) break; + uint nb = end - start + 1; + Pickit::Array cmd = createCommand(2, 2*nb, 2*i); + for (uint k=0; k<nb; k++) { + cmd[5 + 2*k] = data[i + start + k].byte(0); + cmd[6 + 2*k] = data[i + start + k].byte(1); + } + if ( !command(cmd) ) return false; + Port::usleep(100000); + } + monitor.addTaskProgress(data.count()); + Device::Array read; + if ( !readFirmwareCodeMemory(read, &data, monitor) ) return false; + log(Log::DebugLevel::Normal, " Write pickit2 firmware-loaded key"); + Pickit::Array cmd = createCommand(2, 2, 0x7FFE); + cmd[5] = 0x55; + cmd[6] = 0x55; + return command(cmd); +} + +bool Pickit2::USBPort::uploadFirmware(const Pic::Memory &memory, ProgressMonitor &monitor) +{ + if ( !eraseFirmwareCodeMemory() ) return false; + Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Code); + return writeFirmwareCodeMemory(data, monitor); +} + +//----------------------------------------------------------------------------- +bool Pickit2::Hardware::readVoltages(VoltagesData &voltages) +{ + log(Log::DebugLevel::Extra, QString("readVoltages: Firmware is %1").arg(_base.firmwareVersion().pretty())); + if ( _base.firmwareVersion()<VersionData(1, 20, 0) ) { + log(Log::LineType::Warning, i18n("Cannot read voltages with this firmware version.")); + return true; + } + if ( !port().command('M') ) return false; + Array a; + if ( !port().receive(a) ) return false; + voltages[Pic::TargetVdd].value = double(a[1] + a[2]*256) * 5.0 / 65535; + voltages[Pic::TargetVpp].value = double(a[3] + a[4]*256) * (5.0 /65535) * (7.4 / 2.7); + voltages[Pic::TargetVdd].error = ( a[0] & 0x08 ); + voltages[Pic::TargetVpp].error = ( a[0] & 0x10 ); + return true; +} + +bool Pickit2::Hardware::setVddVpp(double vdd, double vpp) +{ + log(Log::DebugLevel::Extra, QString("setVddVpp: Firmware is %1").arg(_base.firmwareVersion().pretty())); + if ( _base.firmwareVersion()<VersionData(1, 20, 0) ) return true; + log(Log::DebugLevel::Normal, QString(" set Vdd = %1 V and Vpp = %2 V").arg(vdd).arg(vpp)); + Array cmd; + cmd[0] = 's'; + uint cvdd = uint(32.0 * vdd + 12.5); + cvdd <<= 6; + cmd[1] = cvdd & 0xC0; + cmd[2] = cvdd >> 8; + uint cvpp = uint(18.61 * vpp); + cmd[3] = 0x40; + cmd[4] = cvpp; + cmd[5] = uchar(4.5 * (cvdd >> 8)); // linit to 75% of vdd + cmd[6] = uchar(0.75 * cvpp); // linit to 75% of vpp + if ( !port().command(cmd) ) return false; + // wait until vpp is stabilized + for (uint i=0; i<30; i++) { + Port::usleep(50000); + VoltagesData voltages; + if ( !readVoltages(voltages) ) return false; + if ( voltages[Pic::TargetVpp].value<(vpp+0.5) ) break; + } + return true; +} + +//----------------------------------------------------------------------------- +bool Pickit2::Baseline::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x08; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0A; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F87XA::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x17; // End externally time programming cycle + cmd[10] = 0x1F; // Bulk Erase program memory + cmd[11] = 0x1F; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F7X::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x08; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit2::P16F716::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P18F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0A; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit2::P18F::doEraseCommand(uint cmd1, uint cmd2) +{ + Array cmd; + cmd[0] = 0x85; + cmd[1] = cmd1; + cmd[2] = cmd2; + return hardware().port().command(cmd); +} + +bool Pickit2::P18F::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x84, 0x00); + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + if ( !doEraseCommand(0x81, 0x00) ) return false; // boot + for (uint i=0; i<device().config().protection().nbBlocks(); i++) + if ( !doEraseCommand(1 << i, 0x80) ) return false; + return true; +} + +bool Pickit2::P18F::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + USBPort &port = static_cast<USBPort &>(hardware().port()); + data.resize(device().nbWords(type)); + QValueVector<uint> words; + switch (type.type()) { + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::Config: { + Pickit::Array cmd = port.createCommand(0x80, data.count(), device().range(type).start.toUInt()); + if ( !port.command(cmd) ) return false; + if ( !hardware().port().receiveWords(1, 1, words) ) return false; + for (uint k=0; k<data.count(); k++) { + data[k] = words[k]; + if ( vdata && !hardware().verifyWord(k, data[k], type, *vdata) ) return false; + } + return true; + } + case Pic::MemoryRangeType::Code: + for (uint i=0; i<data.count();) { + Array cmd; + for (uint k=0; k<8; k++) port.fillCommand(cmd, 0x80, 64, 2*(i + 32 * k), 5*k); + if ( !port.command(cmd) ) return false; + for (uint k=0; k<8; k++) { + if ( !hardware().port().receiveWords(2, 1, words) ) return false; + for (uint k=0; k<32; k++) { + data[i] = words[k]; + if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false; + i++; + } + } + } + _base.progressMonitor().addTaskProgress(data.count()); + return true; + case Pic::MemoryRangeType::Eeprom: + for (uint i=0; i<data.count();) { + Pickit::Array cmd = port.createCommand(0x81, 64, i, false); + if ( !port.command(cmd) ) return false; + if ( !hardware().port().receiveWords(1, 1, words) ) return false; + for (uint k=0; k<64; k++) { + data[i] = words[k]; + if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false; + i++; + } + } + _base.progressMonitor().addTaskProgress(data.count()); + return true; + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +bool Pickit2::P18F::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_UNUSED(force); + USBPort &port = static_cast<USBPort &>(hardware().port()); + switch (type.type()) { + case Pic::MemoryRangeType::UserId: { + Pickit::Array cmd = port.createCommand(0x82, data.count() / 2, device().range(type).start.toUInt()); + for (uint i=0; i<data.count(); i++) cmd[i + 5] = data[i].byte(0); + return port.command(cmd); + } + case Pic::MemoryRangeType::Config: { + Array cmd; + for (uint i=0; i<data.count()/2; i++) { + cmd[4*i] = 0x84; + cmd[1 + 4*i] = 2*i; + cmd[2 + 4*i] = data[2*i].byte(0); + cmd[3 + 4*i] = data[2*i+1].byte(0); + } + return port.command(cmd); + } + case Pic::MemoryRangeType::Code: { + uint nb = Pickit2::data(device().name()).progWidth; + for (uint i=0; i<data.count();) { + bool allBlank = true; + Pickit::Array cmd = port.createCommand(0x82, nb, 2*i); + for (uint k=0; k<nb; k++) { + if ( data[i].byte(0)!=0xFF || data[i].byte(1)!=0xFF ) allBlank = false; + cmd[5 + 2*k] = data[i].byte(0); + cmd[6 + 2*k] = data[i].byte(1); + i++; + } + if ( !allBlank && !port.command(cmd) ) return false; + } + _base.progressMonitor().addTaskProgress(data.count()); + return true; + } + case Pic::MemoryRangeType::Eeprom: + for (uint i=0; i<data.count();) { + bool allBlank = true; + Pickit::Array cmd = port.createCommand(0x87, 32, i, false); + for (uint k=0; k<32; k++) { + if ( data[i].byte(0)!=0xFF ) allBlank = false; + cmd[4+k] = data[i].byte(0); + i++; + } + if ( !allBlank && !port.command(cmd) ) return false; + } + _base.progressMonitor().addTaskProgress(data.count()); + return true; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +bool Pickit2::P18F2X20::doEraseCommand(uint cmd1) +{ + Array cmd; + cmd[0] = 0x86; + cmd[1] = cmd1; + return hardware().port().command(cmd); +} + +bool Pickit2::P18F2X20::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x81); + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + if ( !doEraseCommand(0x83) ) return false; // boot + for (uint i=0; i<device().config().protection().nbBlocks(); i++) + if ( !doEraseCommand(0x88 + i) ) return false; + return true; +} diff --git a/src/progs/pickit2/base/pickit2.h b/src/progs/pickit2/base/pickit2.h new file mode 100644 index 0000000..8efa8ff --- /dev/null +++ b/src/progs/pickit2/base/pickit2.h @@ -0,0 +1,123 @@ +/*************************************************************************** + * 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 PICKIT2_H +#define PICKIT2_H + +#include "pickit.h" +#include "pickit2_data.h" + +namespace Pickit2 +{ +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(64, 'Z', PrintAlphaNum) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit::USBPort +{ +public: + USBPort(Log::Base &log) : Pickit::USBPort(0x0033, log) {} + virtual Pickit::Array array() const { return Array(); } + void fillCommand(Pickit::Array &cmd1, uchar cmd2, uint nbBytes, uint address, uint i, bool longAddress = true) const; + Pickit::Array createCommand(uchar cmd, uint nbBytes, uint address, bool longAddress = true) const; + + bool readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor); + //bool readFirmwareEepromMemory(Device::Array &data); + bool eraseFirmwareCodeMemory(); + bool writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor); + //bool writeFirmwareEepromMemory(const Device::Array &data); + bool resetFirmwareDevice(::Programmer::Mode mode) { return command(mode==::Programmer::BootloadMode ? 'B' : 0xFF); } + bool uploadFirmware(const Pic::Memory &memory, ProgressMonitor &monitor); + +private: + virtual uint readEndPoint() const { return 0x81; } + virtual uint writeEndPoint() const { return 0x01; } +}; + +//----------------------------------------------------------------------------- +class Hardware : public Pickit::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Pickit::Hardware(base, new USBPort(base)) {} + virtual bool readVoltages(VoltagesData &voltages); + bool setVddVpp(double vdd, double vpp); +}; + +//----------------------------------------------------------------------------- +class Baseline : public Pickit::Baseline +{ +public: + Baseline(::Programmer::Base &base) : Pickit::Baseline(base) {} + virtual bool init(); + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Eeprom ? 4 : 16); } +}; + +//----------------------------------------------------------------------------- +class P16F : public Pickit::P16F +{ +public: + P16F(::Programmer::Base &base) : Pickit::P16F(base) {} + virtual bool init(); + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Code ? 16 : 4); } +}; + +class P16F87XA : public P16F +{ +public: + P16F87XA(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +class P16F7X : public P16F +{ +public: + P16F7X(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); + virtual char writeCode() const { return 'w'; } +}; + +class P16F716 : public P16F +{ +public: + P16F716(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +//----------------------------------------------------------------------------- +class P18F : public Pickit::DeviceSpecific +{ +public: + P18F(::Programmer::Base &base) : Pickit::DeviceSpecific(base) {} + Hardware &hardware() { return static_cast<Hardware &>(Pickit::DeviceSpecific::hardware()); } + virtual bool init(); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseCommand(0x87, 0x0F); } + bool doEraseCommand(uint cmd1, uint cmd2); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual char entryMode() const { return data(device().name()).entryMode; } +}; + +class P18F2X20 : public P18F +{ +public: + P18F2X20(::Programmer::Base &base) : P18F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseCommand(0x80); } + bool doEraseCommand(uint cmd); +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2.xml b/src/progs/pickit2/base/pickit2.xml new file mode 100644 index 0000000..044b7bc --- /dev/null +++ b/src/progs/pickit2/base/pickit2.xml @@ -0,0 +1,114 @@ +<!-- ************************************************************************* --> +<!-- * 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="pickit2"> + <device name="10F200" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="10F202" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="10F204" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="10F206" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="10F220" family="Baseline" entry="O" pmode="0" /> + <device name="10F222" family="Baseline" entry="O" pmode="0" /> + <device name="12F508" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="12F509" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="12F510" family="Baseline" entry="O" pmode="0" support_type="tested" /> + <device name="16F505" family="Baseline" entry="O" pmode="0" /> + <device name="16F506" family="Baseline" entry="O" pmode="0" /> + <device name="16F54" family="Baseline" entry="O" pmode="0" /> + <device name="16F57" family="Baseline" entry="O" pmode="0" /> + <device name="16F59" family="Baseline" entry="O" pmode="0" /> + + <device name="12F615" family="P16F" entry="P" pmode="n" pwidth="1" support_type="tested" /> + <device name="12F629" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" /> + <device name="12F635" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="12F675" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" /> + <device name="12F683" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F616" family="P16F" entry="P" pmode="n" pwidth="4" support_type="tested" /> + <device name="16F627A" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F628A" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F630" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" /> + <device name="16F631" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F636" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F639" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F648A" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F676" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" /> + <device name="16F677" family="P16F" entry="P" pmode="1" support_type="tested" /> + <device name="16F684" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F685" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F687" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F688" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F689" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F690" family="P16F" entry="P" pmode="4" support_type="tested" /> + <device name="16F716" family="P16F716" entry="O" pmode="4" /> + <device name="16F73" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F74" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F76" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F77" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F737" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F747" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F767" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F777" family="P16F7X" entry="O" pmode="n" pwidth="2" /> + <device name="16F785" family="P16F" entry="P" pmode="4" /> + <device name="16F818" family="P16F87XA" entry="O" pmode="n" pwidth="4" support_type="tested" /> + <device name="16F819" family="P16F87XA" entry="O" pmode="n" pwidth="4" support_type="tested" /> + <device name="16F87" family="P16F87XA" entry="O" pmode="n" pwidth="4" /> + <device name="16F88" family="P16F87XA" entry="O" pmode="n" pwidth="4" /> + <device name="16F873" family="P16F" entry="O" pmode="n" pwidth="8" /> + <device name="16F874" family="P16F" entry="O" pmode="n" pwidth="8" /> + <device name="16F876" family="P16F" entry="O" pmode="n" pwidth="8" /> + <device name="16F877" family="P16F" entry="O" pmode="n" pwidth="8" /> + <device name="16F873A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F874A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F876A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F877A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F913" family="P16F" entry="O" pmode="n" pwidth="4" support_type="tested" /> + <device name="16F914" family="P16F" entry="O" pmode="n" pwidth="4" support_type="tested" /> + <device name="16F916" family="P16F" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F917" family="P16F" entry="O" pmode="n" pwidth="8" support_type="tested" /> + <device name="16F946" family="P16F" entry="O" pmode="n" pwidth="8" /> + + <device name="18F1220" family="P18F2X20" entry="O" pmode="n" pwidth="4" /> + <device name="18F1320" family="P18F2X20" entry="O" pmode="n" pwidth="4" /> + <device name="18F2220" family="P18F2X20" entry="P" pmode="n" pwidth="4" /> + <device name="18F2221" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2320" family="P18F2X20" entry="P" pmode="n" pwidth="4" /> + <device name="18F2321" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2410" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2420" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2455" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2480" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2510" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2515" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2520" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2525" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2550" family="P18F" entry="P" pmode="n" pwidth="16" support_type="tested" /> + <device name="18F2580" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2585" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2610" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2620" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F2680" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4220" family="P18F2X20" entry="P" pmode="n" pwidth="4" /> + <device name="18F4221" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4320" family="P18F2X20" entry="P" pmode="n" pwidth="4" /> + <device name="18F4321" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4410" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4420" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4455" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4480" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4510" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4515" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4520" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4525" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4550" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4580" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4585" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4610" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4620" family="P18F" entry="P" pmode="n" pwidth="16" /> + <device name="18F4680" family="P18F" entry="P" pmode="n" pwidth="16" /> +</type> diff --git a/src/progs/pickit2/base/pickit2_data.h b/src/progs/pickit2/base/pickit2_data.h new file mode 100644 index 0000000..abae867 --- /dev/null +++ b/src/progs/pickit2/base/pickit2_data.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * 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 PICKIT2_DATA_H +#define PICKIT2_DATA_H + +#include <qstring.h> + +namespace Pickit2 +{ + struct Data { + char entryMode, progMode; + uchar progWidth; + bool regenerateOsccal; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2_prog.cpp b/src/progs/pickit2/base/pickit2_prog.cpp new file mode 100644 index 0000000..88b73b9 --- /dev/null +++ b/src/progs/pickit2/base/pickit2_prog.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * 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 "pickit2_prog.h" + +#include "devices/list/device_list.h" +#include "pickit2.h" + +//---------------------------------------------------------------------------- +VersionData Pickit2::Base::firmwareVersion(Programmer::FirmwareVersionType type) const +{ + switch (type.type()) { + case Programmer::FirmwareVersionType::Min: return VersionData(1, 10, 0); + case Programmer::FirmwareVersionType::Recommended: + case Programmer::FirmwareVersionType::Max: return VersionData(1, 20, 0); + case Programmer::FirmwareVersionType::Nb_Types: break; + } + Q_ASSERT(false); + return VersionData(); +} + +bool Pickit2::Base::deviceHasOsccalRegeneration() const +{ + return data(device()->name()).regenerateOsccal; +} + +bool Pickit2::Base::setTarget() +{ + // #### FIXME: this needs to test for 18J first to protected them + if ( !static_cast<Pickit2::Hardware &>(hardware()).setVddVpp(5.0, 12.0) ) return false; + return static_cast<Pickit::DeviceSpecific *>(_specific)->init(); +} + +bool Pickit2::Base::internalEnterMode(::Programmer::Mode mode) +{ + USBPort &port = static_cast<USBPort &>(hardware().port()); + if ( !port.resetFirmwareDevice(mode) ) return false; + log(Log::DebugLevel::Extra, "disconnecting and try to reconnect PICkit2 in new mode..."); + disconnectHardware(); + Port::usleep(3000000); + return connectHardware(); +} + +bool Pickit2::Base::doUploadFirmware(PURL::File &file) +{ + const Pic::Data &data = static_cast<const Pic::Data &>(*Device::lister().data("18F2550")); + Pic::Memory memory(static_cast<const Pic::Data &>(data)); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\" (%2).").arg(file.url().pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 18F2550 inside PICkit2.")); + return false; + } + log(Log::LineType::Information, i18n(" Uploading PICkit2 firmware...")); + if ( !enterMode(::Programmer::BootloadMode) ) return false; + _progressMonitor.insertTask(i18n("Uploading Firmware..."), 2*data.nbWords(Pic::MemoryRangeType::Code)); + if ( !static_cast<USBPort &>(hardware().port()).uploadFirmware(memory, _progressMonitor) ) { + log(Log::LineType::Error, i18n("Failed to upload firmware.")); + return false; + } + log(Log::LineType::Information, i18n("Firmware succesfully uploaded.")); + return enterMode(::Programmer::NormalMode); +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} diff --git a/src/progs/pickit2/base/pickit2_prog.h b/src/progs/pickit2/base/pickit2_prog.h new file mode 100644 index 0000000..5a67e2a --- /dev/null +++ b/src/progs/pickit2/base/pickit2_prog.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * 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 PICKIT2_PROG_H +#define PICKIT2_PROG_H + +#include "common/global/global.h" +#include "pickit_prog.h" + +namespace Pickit2 +{ +//---------------------------------------------------------------------------- +class Base : public Pickit::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) : Pickit::Base(group, data) {} + virtual bool deviceHasOsccalRegeneration() const; + virtual bool setTarget(); + +private: + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual bool internalEnterMode(::Programmer::Mode mode); + virtual bool doUploadFirmware(PURL::File &file); +}; + +//---------------------------------------------------------------------------- +class Group : public Pickit::Group +{ +public: + virtual QString name() const { return "pickit2"; } + virtual QString label() const { return i18n("PICkit2 Firmware 1.x"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit2::Base(*this, static_cast<const Pic::Data *>(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit_prog.cpp b/src/progs/pickit2/base/pickit_prog.cpp new file mode 100644 index 0000000..c11dd08 --- /dev/null +++ b/src/progs/pickit2/base/pickit_prog.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * 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 "pickit_prog.h" + +#include "common/global/global.h" +#include "pickit.h" +#include "progs/base/prog_config.h" + +Pickit::Base::Base(const Programmer::Group &group, const Pic::Data *data) + : ::Programmer::PicBase(group, data, "pickit_programmer") +{} + +Pickit::Hardware &Pickit::Base::hardware() +{ + return static_cast<Hardware &>(*_hardware); +} + +bool Pickit::Base::readFirmwareVersion() +{ + return hardware().port().getMode(_firmwareVersion, _mode); +} + +bool Pickit::Base::regenerateOsccal(const PURL::Url &url) +{ + log(Log::DebugLevel::Normal, QString(" Calibration firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + Pic::Memory memory(*device()); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read calibration firmware file \"%1\" (%2).").arg(url.pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Calibration firmware file seems incompatible with selected device %1.").arg(device()->name())); + return false; + } + if ( !askContinue(i18n("This will overwrite the device code memory. Continue anyway?")) ) return false; + if ( !program(memory, Pic::MemoryRange(Pic::MemoryRangeType::Nb_Types)) ) return false; + Device::Array array(1); + if ( !static_cast<Hardware &>(hardware()).regenerateOsccal(array[0]) ) return false; + return programCalibration(array); +} diff --git a/src/progs/pickit2/base/pickit_prog.h b/src/progs/pickit2/base/pickit_prog.h new file mode 100644 index 0000000..b35fc92 --- /dev/null +++ b/src/progs/pickit2/base/pickit_prog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * 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 PICKIT_PROG_H +#define PICKIT_PROG_H + +#include "common/global/global.h" +#include "progs/icd2/base/microchip.h" +#include "progs/base/prog_group.h" +#include "pickit.h" + +namespace Pickit +{ +class Hardware; + +//---------------------------------------------------------------------------- +class Base : public Programmer::PicBase +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data); + virtual bool deviceHasOsccalRegeneration() const = 0; + bool regenerateOsccal(const PURL::Url &url); + virtual bool readFirmwareVersion(); + +protected: + Hardware &hardware(); +}; + +//---------------------------------------------------------------------------- +class Group : public Programmer::PicGroup +{ +public: + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::USB ); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/gui/Makefile.am b/src/progs/pickit2/gui/Makefile.am new file mode 100644 index 0000000..d2fa763 --- /dev/null +++ b/src/progs/pickit2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2ui.la +libpickit2ui_la_SOURCES = pickit2_group_ui.cpp +libpickit2ui_la_LDFLAGS = $(all_libraries)
\ No newline at end of file diff --git a/src/progs/pickit2/gui/pickit2_group_ui.cpp b/src/progs/pickit2/gui/pickit2_group_ui.cpp new file mode 100644 index 0000000..f36395a --- /dev/null +++ b/src/progs/pickit2/gui/pickit2_group_ui.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * 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 "pickit2_group_ui.h" + +#include <kfiledialog.h> + +#include "common/global/purl.h" +#include "common/gui/misc_gui.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit2/base/pickit2.h" + +//---------------------------------------------------------------------------- +Pickit::AdvancedDialog::AdvancedDialog(Base &base, QWidget *parent, const char *name) + : ::Programmer::PicAdvancedDialog(base, parent, name) +{} + +void Pickit::AdvancedDialog::regenerateCalibration() +{ + if ( !base().deviceHasOsccalRegeneration() ) { + MessageBox::sorry(i18n("Osccal regeneration not available for the selected device."), Log::Show); + return; + } + KFileDialog dialog(":open_autohex", PURL::filter(PURL::Hex), this, "autohex_dialog", true); + dialog.setOperationMode(KFileDialog::Opening); + dialog.setCaption(i18n("Open Calibration Firmware")); + dialog.setMode(KFile::File); + //dialog.ops->clearHistory(); + dialog.setSelection("autocal.hex"); + dialog.exec(); + PURL::Url url(dialog.selectedURL()); + if ( url.isEmpty() ) return; + base().regenerateOsccal(url); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Pickit2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new Pickit::AdvancedDialog(static_cast<Base &>(base), parent, "pickit2_advanced_dialog"); +} diff --git a/src/progs/pickit2/gui/pickit2_group_ui.h b/src/progs/pickit2/gui/pickit2_group_ui.h new file mode 100644 index 0000000..f79aa1f --- /dev/null +++ b/src/progs/pickit2/gui/pickit2_group_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 PICKIT2_GROUP_UI_H +#define PICKIT2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/pickit2/base/pickit_prog.h" + +//---------------------------------------------------------------------------- +namespace Pickit +{ +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(Base &base, QWidget *parent, const char *name); + Base &base() { return static_cast<Base &>(_base); } + +public slots: + virtual void regenerateCalibration(); +}; +} // namespace + +//---------------------------------------------------------------------------- +namespace Pickit2 +{ +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/pickit2/pickit2.pro b/src/progs/pickit2/pickit2.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit2/pickit2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit2/xml/Makefile.am b/src/progs/pickit2/xml/Makefile.am new file mode 100644 index 0000000..5e8197e --- /dev/null +++ b/src/progs/pickit2/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit2_parser +xml_pickit2_parser_SOURCES = xml_pickit2_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit2_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit2_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit2/xml/xml.pro b/src/progs/pickit2/xml/xml.pro new file mode 100644 index 0000000..0604fbb --- /dev/null +++ b/src/progs/pickit2/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit2_parser +SOURCES += xml_pickit2_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit2_parser +unix:QMAKE_CLEAN += ../base/pickit2_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit2_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit2_data.cpp diff --git a/src/progs/pickit2/xml/xml_pickit2_parser.cpp b/src/progs/pickit2/xml/xml_pickit2_parser.cpp new file mode 100644 index 0000000..ffc82f7 --- /dev/null +++ b/src/progs/pickit2/xml/xml_pickit2_parser.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "progs/pickit2/base/pickit2_data.h" + +namespace Pickit2 +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("pickit2", "Pickit2") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Pickit2::XmlToData::parseData(QDomElement element, Data &data) +{ + QString s = element.attribute("entry"); + if ( s.length()!=1 || (s[0]!='O' && s[0]!='P') ) qFatal("Invalid or missing entry mode"); + data.entryMode = s[0].latin1(); + s = element.attribute("pmode"); + if ( s.length()!=1 || (s[0]!='0' && s[0]!='1' && s[0]!='4' && s[0]!='n') ) + qFatal("Invalid or missing program mode"); + data.progMode = s[0].latin1(); + s = element.attribute("pwidth"); + if ( data.progMode!='n' ) { + if ( s.length()!=0 ) qFatal("Program width should not be defined"); + data.progWidth = 0; + } else { + bool ok; + data.progWidth = s.toUInt(&ok); + if ( !ok ) qFatal("Invalid or missing program width"); + } + s = element.attribute("regen"); + if ( s.isEmpty() || s=="false" ) data.regenerateOsccal = false; + else if ( s=="true" ) data.regenerateOsccal = true; + else qFatal("Invalid regen value"); +} + +void Pickit2::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << "'" << data.entryMode << "', '" << data.progMode; + s << "', " << data.progWidth << ", " << (data.regenerateOsccal ? "true" : "false"); +} + +void Pickit2::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData<Data>::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Group::createDeviceSpecific(::Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast< ::Pickit2::Base &>(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i<uint(families().count()); i++) { + s << " case " + QString::number(i) + ": return new " + families()[i] + "(base);" << endl; + } + s << " }" << endl; + s << " Q_ASSERT(false);" << endl; + s << " return 0;" << endl; + s << "}" << endl; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Pickit2::XmlToData) diff --git a/src/progs/pickit2_bootloader/Makefile.am b/src/progs/pickit2_bootloader/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/pickit2_bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/pickit2_bootloader/base/Makefile.am b/src/progs/pickit2_bootloader/base/Makefile.am new file mode 100644 index 0000000..db87222 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2bootloader.la +libpickit2bootloader_la_SOURCES = pickit2_bootloader_data.cpp pickit2_bootloader_prog.cpp pickit2_bootloader.cpp +libpickit2bootloader_la_DEPENDENCIES = pickit2_bootloader_data.cpp + +noinst_DATA = pickit2_bootloader.xml +pickit2_bootloader_data.cpp: ../xml/xml_pickit2_bootloader_parser pickit2_bootloader.xml + ../xml/xml_pickit2_bootloader_parser +CLEANFILES = pickit2_bootloader_data.cpp diff --git a/src/progs/pickit2_bootloader/base/base.pro b/src/progs/pickit2_bootloader/base/base.pro new file mode 100644 index 0000000..9a2fe76 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit2_bootloader +HEADERS += pickit2_bootloader.h pickit2_bootloader_prog.h pickit2_bootloader_data.h +SOURCES += pickit2_bootloader.cpp pickit2_bootloader_prog.cpp pickit2_bootloader_data.cpp diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader.cpp b/src/progs/pickit2_bootloader/base/pickit2_bootloader.cpp new file mode 100644 index 0000000..d080481 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2_bootloader.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::Hardware::Hardware(::Programmer::Base &base) + : Bootloader::Hardware(base, new Pickit2::USBPort(base)) +{} + +bool Pickit2Bootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + ::Programmer::Mode mode; + VersionData version; + if ( !port().getMode(version, mode) ) return false; + if ( mode!=::Programmer::BootloadMode ) { + log(Log::LineType::Information, i18n("Trying to enter bootloader mode...")); + if ( !port().resetFirmwareDevice(::Programmer::BootloadMode) ) return false; + for (uint i=0;; i++) { + port().close(); + Port::usleep(500000); // ?? + if ( !openPort() ) continue; + if ( !port().getMode(version, mode) ) continue; + if ( i==4 || mode!=::Programmer::BootloadMode ) { + log(Log::LineType::Error, i18n("Could not detect device in bootloader mode.")); + return false; + } + } + } + log(Log::LineType::Information, i18n("Bootloader version %1 detected.").arg(version.pretty())); + if ( version.majorNum()!=2 ) { + log(Log::LineType::Error, i18n("Only bootloader version 2.x is supported.")); + return false; + } + return true; +} + +bool Pickit2Bootloader::Hardware::write(Pic::MemoryRangeType type, const Device::Array &data) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + // check that there is nothing in bootloader reserved area + for (uint i=0; i<data.count(); i++) { + if ( i>=0x1000 && i<0x3FF0 ) continue; + if ( data[i]==device().mask(Pic::MemoryRangeType::Code) ) continue; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + log(Log::LineType::Warning, " " + i18n("Code is present in bootloader reserved area (at address %1). It will be ignored.").arg(toHexLabel(address, device().nbCharsAddress()))); + break; + } + return port().writeFirmwareCodeMemory(data, _base.progressMonitor()); +} + +bool Pickit2Bootloader::Hardware::read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + data.resize(device().nbWords(type)); + Device::Array varray; + if (vdata) varray = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(Pic::MemoryRangeType::Code); + return port().readFirmwareCodeMemory(data, vdata ? &varray : 0, _base.progressMonitor()); +} + +//----------------------------------------------------------------------------- +bool Pickit2Bootloader::DeviceSpecific::doEraseRange(Pic::MemoryRangeType type) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + return static_cast<Hardware &>(hardware()).port().eraseFirmwareCodeMemory(); +} diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader.h new file mode 100644 index 0000000..7af0957 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2_BOOTLOADER_H +#define PICKIT2_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "progs/pickit2/base/pickit2.h" + +namespace Pickit2Bootloader +{ +//----------------------------------------------------------------------------- +class Hardware : public Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base); + Pickit2::USBPort &port() { return static_cast<Pickit2::USBPort &>(*_port); } + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool internalConnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool canReadRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool canWriteRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml b/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml new file mode 100644 index 0000000..2e87949 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml @@ -0,0 +1,16 @@ +<!-- ************************************************************************* --> +<!-- * Copyright (C) 2007 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="pickit2_bootloader"> + <device name="18F2455" family="generic" /> + <device name="18F2550" family="generic" /> + <device name="18F4455" family="generic" /> + <device name="18F4550" family="generic" /> +</type> diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h new file mode 100644 index 0000000..87aead1 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2_BOOTLOADER_DATA_H +#define PICKIT2_BOOTLOADER_DATA_H + +namespace Pickit2Bootloader +{ + struct Data {}; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp new file mode 100644 index 0000000..7f734ba --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2_bootloader_prog.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "pickit2_bootloader_programmer_base") +{} diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h new file mode 100644 index 0000000..461d734 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2_BOOTLOADER_PROG_H +#define PICKIT2_BOOTLOADER_PROG_H + +#include "progs/bootloader/base/bootloader_prog.h" +#include "pickit2_bootloader.h" + +namespace Pickit2Bootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public ::Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); + virtual bool verifyDeviceId() { return true; } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "pickit2_bootloader"; } + virtual QString label() const { return i18n("Pickit2 Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::USB; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const { return new Hardware(base); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/gui/Makefile.am b/src/progs/pickit2_bootloader/gui/Makefile.am new file mode 100644 index 0000000..b9be2b0 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2bootloaderui.la +libpickit2bootloaderui_la_LDFLAGS = $(all_libraries) +libpickit2bootloaderui_la_SOURCES = pickit2_bootloader_ui.cpp diff --git a/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp new file mode 100644 index 0000000..89bf5c7 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2_bootloader_ui.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::ConfigWidget::ConfigWidget(const::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *Pickit2Bootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} diff --git a/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h new file mode 100644 index 0000000..d715574 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2_BOOTLOADER_UI_H +#define PICKIT2_BOOTLOADER_UI_H + +#include "progs/bootloader/gui/bootloader_ui.h" + +//----------------------------------------------------------------------------- +namespace Pickit2Bootloader +{ +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const::Programmer::Group &group, QWidget *parent); + virtual void loadConfig() {} + virtual void saveConfig() {} +}; + + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/pickit2_bootloader.pro b/src/progs/pickit2_bootloader/pickit2_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit2_bootloader/pickit2_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit2_bootloader/xml/Makefile.am b/src/progs/pickit2_bootloader/xml/Makefile.am new file mode 100644 index 0000000..899aa3b --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit2_bootloader_parser +xml_pickit2_bootloader_parser_SOURCES = xml_pickit2_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit2_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit2_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit2_bootloader/xml/xml.pro b/src/progs/pickit2_bootloader/xml/xml.pro new file mode 100644 index 0000000..2e2aef1 --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit2_bootloader_parser +SOURCES += xml_pickit2_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit2_bootloader_parser +unix:QMAKE_CLEAN += ../base/pickit2_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit2_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit2_bootloader_data.cpp diff --git a/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp b/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp new file mode 100644 index 0000000..150e814 --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "xml_to_data/prog_xml_to_data.h" + +#include "progs/pickit2_bootloader/base/pickit2_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace Pickit2Bootloader +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("pickit2_bootloader", "Pickit2Bootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); +}; + +void Pickit2Bootloader::XmlToData::parseData(QDomElement, Data &) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast<const Pic::Data *>(ddata); + if ( !pdata->hasFeature(Pic::Feature::USB) ) qFatal("device does not have USB"); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Pickit2Bootloader::XmlToData) diff --git a/src/progs/pickit2v2/Makefile.am b/src/progs/pickit2v2/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/pickit2v2/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/pickit2v2/base/Makefile.am b/src/progs/pickit2v2/base/Makefile.am new file mode 100644 index 0000000..b5a7688 --- /dev/null +++ b/src/progs/pickit2v2/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2v2.la +libpickit2v2_la_DEPENDENCIES = pickit2v2_data.cpp +libpickit2v2_la_SOURCES = pickit2v2.cpp pickit2v2_data.cpp pickit2v2_prog.cpp diff --git a/src/progs/pickit2v2/base/base.pro b/src/progs/pickit2v2/base/base.pro new file mode 100644 index 0000000..70ccaef --- /dev/null +++ b/src/progs/pickit2v2/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit2v2 +HEADERS += pickit2v2.h pickit2v2_prog.h pickit2v2_data.h +SOURCES += pickit2v2.cpp pickit2v2_prog.cpp pickit2v2_data.cpp diff --git a/src/progs/pickit2v2/base/pickit2v2.cpp b/src/progs/pickit2v2/base/pickit2v2.cpp new file mode 100644 index 0000000..31dd6ca --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2.cpp @@ -0,0 +1,432 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2v2.h" + +#include "progs/base/prog_config.h" +#include "progs/icd2/base/microchip.h" +#include "pickit2v2_data.h" + +//----------------------------------------------------------------------------- +const Pickit2V2::FamilyData *Pickit2V2::familyData(const Pic::Data &device) +{ + for (uint i=0; FAMILY_DATA[i].architecture!=Pic::Architecture::Nb_Types; i++) + if ( FAMILY_DATA[i].architecture==device.architecture() ) return &FAMILY_DATA[i]; + Q_ASSERT(false); + return 0; +} + +//----------------------------------------------------------------------------- +Pickit2V2::Hardware::Hardware(::Programmer::Base &base) + : ::Programmer::PicHardware(base, new USBPort(base), QString::null), + _scriptBufferChecksum(0), _deviceSet(false) +{} + +bool Pickit2V2::Hardware::internalConnectHardware() +{ + return port().open(); +} + +bool Pickit2V2::Hardware::setTarget() +{ + //setIcspSpeed(0); // #### ?? + _fastProgramming = true; // #### ?? + uint checksum; + if ( !getScriptBufferChecksum(checksum) ) return false; + if ( !_deviceSet || _scriptBufferChecksum!=checksum ) { + if ( !downloadScripts() ) return false; + } + _deviceSet = true; + return true; +} + +bool Pickit2V2::Hardware::readStatus(ushort &status) +{ + if ( !port().command(ReadStatus) ) return false; + Array a; + if ( !port().receive(a) ) return false; + status = (a[1] << 8) + a[0]; + return true; +} + +bool Pickit2V2::Hardware::sendScript(const ushort *script, uint length) +{ + Array cmd; + cmd[0] = ClearUploadBuffer; + cmd[1] = ExecuteScript; + cmd[2] = length; + for (uint i=0; i<length; i++) cmd[3+i] = script[i]; + return port().command(cmd); +} + +bool Pickit2V2::Hardware::executeScript(uint i) +{ + Q_ASSERT( i!=0 ); + const ScriptData &sdata = SCRIPT_DATA[i-1]; + log(Log::DebugLevel::Extra, QString("execute script #%1: %2").arg(i).arg(sdata.name)); + return sendScript(sdata.data, sdata.length); +} + +bool Pickit2V2::Hardware::getScriptBufferChecksum(uint &checksum) +{ + if ( !port().command(ScriptBufferChecksum) ) return false; + Array array; + if ( !port().receive(array) ) return false; + checksum = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3]; + log(Log::DebugLevel::Extra, QString("get script buffer checksum: %1").arg(toHexLabel(checksum, 8))); + return true; +} + +bool Pickit2V2::Hardware::downloadScript(ScriptType type, uint i) +{ + if (i==0 ) return true; // empty script + const ScriptData &sdata = SCRIPT_DATA[i-1]; + log(Log::DebugLevel::Max, QString(" download script #%1 (\"%2\") at position #%3") + .arg(i-1).arg(sdata.name).arg(toHexLabel(type, 2))); + Array cmd; + cmd[0] = DownloadScript; + cmd[1] = type; + cmd[2] = sdata.length; + for (uint k=0; k<sdata.length; k++) { + if ( !_fastProgramming && sdata.data[k]==0xAAE7 ) { + ushort next = sdata.data[k+1]; + if ( (next & 0xFF)<170 && next!=0 ) { + cmd[3+k] = sdata.data[k]; + cmd[3+k+1] = next + next/2; + } else { + cmd[3+k] = DelayLong; + cmd[3+k+1] = 2; + } + k++; + } else if ( !_fastProgramming && sdata.data[k]==0xAAE8 ) { + ushort next = sdata.data[k+1]; + if ( (next & 0xFF)<171 && next!=0 ) { + cmd[3+k] = sdata.data[k]; + cmd[3+k+1] = next + next/2; + } else { + cmd[3+k] = DelayLong; + cmd[3+k+1] = 0; + } + k++; + } else cmd[3+k] = sdata.data[k]; + } + return port().command(cmd); +} + +bool Pickit2V2::Hardware::downloadScripts() +{ + if ( !port().command(ClearDownloadBuffer) ) return false; + log(Log::DebugLevel::Extra, "clear scripts buffer"); + if ( !port().command(ClearScriptBuffer) ) return false; + log(Log::DebugLevel::Extra, "download scripts"); + const Data &d = data(device().name()); + for (uint i=0; i<Nb_ScriptTypes; i++) { + if ( i==TestMemoryRead || i==ConfigErase ) continue; // ### to get same checksum as pk2cmd + if ( !downloadScript(ScriptType(i), d.scriptIndexes[i]) ) return false; + } + return getScriptBufferChecksum(_scriptBufferChecksum); +} + +bool Pickit2V2::Hardware::setTargetReset(Pic::ResetMode mode) +{ + ushort script[1]; + switch (mode) { + case Pic::ResetHeld: script[0] = MclrGroundOn; break; + case Pic::ResetReleased: script[0] = MclrGroundOff; break; + case Pic::Nb_ResetModes: Q_ASSERT(false); return false; + } + return sendScript(script, 1); +} + +bool Pickit2V2::Hardware::setVddVoltage(double value, double threshold) +{ + ushort v = ushort(qRound(32.0*value + 10.5)) << 6; + uchar vfault = uchar(qRound(256.0 * (threshold * value) / 5.0)); + if ( vfault>210 ) vfault = 210; + Array cmd; + cmd[0] = SetVdd; + cmd[1] = v & 0xFF; + cmd[2] = v >> 8; + cmd[3] = vfault; + return port().command(cmd); +} + +bool Pickit2V2::Hardware::setVppVoltage(double value, double threshold) +{ + Array cmd; + cmd[0] = SetVpp; + cmd[1] = 0x40; + cmd[2] = uchar(qRound(18.61*value)); + cmd[3] = uchar(qRound(18.61*value*threshold)); + return port().command(cmd); +} + +bool Pickit2V2::Hardware::setVddOn(bool on) +{ + log(Log::DebugLevel::Extra, QString("Vdd set to %1, self powered is %2").arg(on).arg(_base.isTargetSelfPowered())); + ushort script[2]; + script[0] = (on ? VddGroundOff : VddOff); + if ( _base.isTargetSelfPowered() ) script[1] = (on ? VddOff : VddGroundOff); + else script[1] = (on ? VddOn : VddGroundOn); + return sendScript(script, 2); +} + +bool Pickit2V2::Hardware::setIcspSpeed(uchar speed) +{ + ushort script[2]; + script[0] = SetIcspSpeed; + script[1] = speed; + return sendScript(script, 2); +} + +bool Pickit2V2::Hardware::getMode(VersionData &version, ::Programmer::Mode &mode) +{ + if ( !port().command(FirmwareVersion) ) return false; + Array data; + if ( !port().receive(data) ) return false; + if ( data[0]=='B' ) { + mode = ::Programmer::BootloadMode; + version = VersionData(); + } else { + mode = ::Programmer::NormalMode; + version = VersionData(data[0], data[1], data[2]); + } + return true; +} + +bool Pickit2V2::Hardware::readVoltages(VoltagesData &voltagesData) +{ + if ( !port().command(ReadVoltages) ) return false; + Array array; + if ( !port().receive(array) ) return false; + double vadc = 256 * array[1] + array[0]; + voltagesData[Pic::TargetVdd].value = 5.0 * (vadc / 65536); + voltagesData[Pic::TargetVdd].error = false; + vadc = 256 * array[3] + array[2]; + voltagesData[Pic::TargetVpp].value = 13.7 * (vadc / 65536); + voltagesData[Pic::TargetVpp].error = false; + return true; +} + +bool Pickit2V2::Hardware::downloadAddress(Address address) +{ + log(Log::DebugLevel::Max, QString("download address %1").arg(toHexLabel(address, 6))); + Array cmd; + cmd[0] = ClearDownloadBuffer; + cmd[1] = DownloadData; + cmd[2] = 3; + cmd[3] = address.toUInt() & 0xFF; + cmd[4] = (address.toUInt() >> 8) & 0xFF; + cmd[5] = (address.toUInt() >> 16) & 0xFF; + return port().command(cmd); +} + +bool Pickit2V2::Hardware::runScript(ScriptType stype, uint repetitions, uint nbNoLens) +{ + log(Log::DebugLevel::Max, QString("run script %1: repetitions=%2 nbNoLen=%3") + .arg(toHexLabel(stype, 2)).arg(repetitions).arg(nbNoLens)); +#if 0 // ALTERNATE METHOD + const Data &d = data(device().name()); + for (uint i=0; i<repetitions; i++) + if ( !executeScript(d.scriptIndexes[stype]) ) return false; + if (nbNoLens) { + Array cmd; + for (uint i=0; i<nbNoLens; i++) cmd[i] = UploadDataNoLen; + if ( !port().command(cmd) ) return false; + } +#else + Array cmd; + cmd[0] = ClearUploadBuffer; + cmd[1] = RunScript; + cmd[2] = stype; + cmd[3] = repetitions; + for (uint i=0; i<nbNoLens; i++) cmd[4+i] = UploadDataNoLen; + if ( !port().command(cmd) ) return false; +#endif + if ( stype==ProgExit && !setTargetReset(Pic::ResetReleased) ) return false; + return true; +} + +bool Pickit2V2::Hardware::prepareRead(Pic::MemoryRangeType type, uint wordIndex) +{ + ScriptType stype = prepareReadScript(type); + if ( type!=Pic::MemoryRangeType::Cal && (stype==Nb_ScriptTypes || data(device().name()).scriptIndexes[stype]==0) ) return true; + switch (type.type()) { + case Pic::MemoryRangeType::Code: + if ( !device().architecture().data().hasAddressAccess ) return true; + if ( !downloadAddress(0x10000 * (wordIndex / 0x8000)) ) return false; + break; + case Pic::MemoryRangeType::Eeprom: + if ( device().nbBytesWord(Pic::MemoryRangeType::Eeprom)==4 ) { + if ( !downloadAddress(device().range(Pic::MemoryRangeType::Eeprom).start.toUInt()) ) return false; // #### correct ? + } else if ( !downloadAddress(0x0) ) return false; + break; + case Pic::MemoryRangeType::Config: return true; // ConfigPrepareRead unused (?) + case Pic::MemoryRangeType::UserId: break; + case Pic::MemoryRangeType::Cal: { + Address start = device().range(Pic::MemoryRangeType::Cal).start; + Q_ASSERT( start==device().range(Pic::MemoryRangeType::Code).end+1 ); + return downloadAddress(start.toUInt()); + } + default: return true; + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + return runScript(stype); +} + +bool Pickit2V2::Hardware::readMemory(Pic::MemoryRangeType otype, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + uint nbWords = device().nbWords(otype); + data.resize(nbWords); + log(Log::DebugLevel::Max, QString("read %1 nbWords=%2").arg(otype.label()).arg(nbWords)); + uint nbBytesWord = device().nbBytesWord(otype); + // EEPROM is read like regular program memory in midrange + if ( !device().is18Family() && !device().is16bitFamily() && otype==Pic::MemoryRangeType::Eeprom ) nbBytesWord = 2; + uint wordOffset = 0; + Pic::MemoryRangeType type = otype; + if ( otype==Pic::MemoryRangeType::Config && device().range(Pic::MemoryRangeType::Config).start==device().range(Pic::MemoryRangeType::Code).end+1 ) { // config in code memory + wordOffset = device().range(Pic::MemoryRangeType::Config).start.toUInt(); + type = Pic::MemoryRangeType::Code; + } + bool setAddress = true; + ScriptType stype = readScript(type); + Q_ASSERT( stype!=Nb_ScriptTypes ); + const FamilyData *fdata = familyData(device()); + uint nbRunWords = QMIN(UploadBufferNbBytes / nbBytesWord, nbWords); + uint nbRuns = 1; + uint nbReceive = (nbRunWords*nbBytesWord + 63) / 64; + switch (type.type()) { + case Pic::MemoryRangeType::Code: nbRuns = nbRunWords / Pickit2V2::data(device().name()).codeMemoryNbReadWords; break; + case Pic::MemoryRangeType::Eeprom: nbRuns = nbRunWords / Pickit2V2::data(device().name()).eepromMemoryNbReadWords; break; + default: break; + } + + if ( !runScript(ProgEntry) ) return false; + for (uint i=0; i<nbWords; ) { + if (setAddress) { + setAddress = false; + if ( !prepareRead(type, wordOffset + i) ) return false; + } + QValueVector<uint> words; + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::Cal ) { + if ( !runScript(stype, 1, 0) ) return false; + if ( !port().command(UploadData) ) return false; + // config memory return includes a length byte that we need to ignore + if ( !port().receiveWords(nbBytesWord, nbReceive, words, 1) ) return false; + } else { + if ( !runScript(stype, nbRuns, nbReceive) ) return false; + if ( !port().receiveWords(nbBytesWord, nbReceive, words) ) return false; + } + log(Log::DebugLevel::Max, QString("nbRunWords=%1 readNbWords=%2 index=%3/%4").arg(nbRunWords).arg(words.count()).arg(i).arg(nbWords)); + for (uint k=0; k<words.count(); k++) { + if ( i>=nbWords ) break; + data[i] = words[k]; + if (fdata->progMemShift) data[i] >>= 1; + data[i] = data[i].maskWith(device().mask(type)); // ### correct ? + if ( vdata && !verifyWord(i, data[i], type, *vdata) ) return false; + if ( type==Pic::MemoryRangeType::Code && i!=0x0 && i%0x8000==0 ) setAddress = true; + i++; + } + } + if ( !runScript(ProgExit) ) return false; + return true; +} + +bool Pickit2V2::Hardware::eraseAll() +{ + const Data &d = data(device().name()); + if ( d.scriptIndexes[ConfigErase]!=0 ) { + if ( !runScript(ProgEntry) ) return false; + if ( d.scriptIndexes[ConfigWritePrepare]!=0 ) { + if ( !downloadAddress(0) ) return false; + if ( !runScript(ConfigWritePrepare) ) return false; + } + if ( !runScript(ConfigErase) ) return false; + if ( !runScript(ProgExit) ) return false; + } + if ( !runScript(ProgEntry) ) return false; + if ( d.scriptIndexes[EraseChipPrepare]!=0 && !runScript(EraseChipPrepare) ) return false; + if ( !runScript(ChipErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; +} + +bool Pickit2V2::Hardware::eraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + if ( !runScript(ProgEntry) ) return false; + if ( !runScript(ProgMemoryErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + if ( !runScript(ProgEntry) ) return false; + if ( !runScript(EepromErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; + } + Q_ASSERT(false); + return false; +} + +bool Pickit2V2::Hardware::prepareWrite(Pic::MemoryRangeType type, uint wordIndex) +{ + ScriptType stype = prepareWriteScript(type); + if ( stype==Nb_ScriptTypes || data(device().name()).scriptIndexes[stype]==0 ) return true; + switch (type.type()) { + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Config: + if ( !device().architecture().data().hasAddressAccess ) return true; + if ( !downloadAddress(0x10000 * (wordIndex / 0x8000)) ) return false; + break; + case Pic::MemoryRangeType::Eeprom: { + Address address = (device().nbBytesWord(Pic::MemoryRangeType::Eeprom)==4 ? device().range(Pic::MemoryRangeType::Eeprom).start : 0x000000); + if ( !downloadAddress(address) ) return false; + break; + } + case Pic::MemoryRangeType::UserId: break; + default: return true; + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + return runScript(stype); +} + +bool Pickit2V2::Hardware::writeMemory(Pic::MemoryRangeType otype, const Device::Array &data, bool force) +{ + Q_UNUSED(force); + return false; // ### TODO +} + +//----------------------------------------------------------------------------- +bool Pickit2V2::DeviceSpecific::canEraseRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Code ) return d.scriptIndexes[ProgMemoryErase]; + if ( type==Pic::MemoryRangeType::Eeprom ) return d.scriptIndexes[EepromErase]; + return false; +} + +bool Pickit2V2::DeviceSpecific::canReadRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Cal ) return d.scriptIndexes[OsccalRead]; + return true; +} + +bool Pickit2V2::DeviceSpecific::canWriteRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Cal ) return d.scriptIndexes[OsccalWrite]; + return true; +} + +bool Pickit2V2::DeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_ASSERT( data.size()==device().nbWords(type) ); + return hardware().writeMemory(type, data, force); +} diff --git a/src/progs/pickit2v2/base/pickit2v2.h b/src/progs/pickit2v2/base/pickit2v2.h new file mode 100644 index 0000000..7c6f294 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2.h @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2V2_H +#define PICKIT2V2_H + +#include "progs/pickit2/base/pickit2.h" +#include "pickit2v2_data.h" + +namespace Pickit2V2 +{ +//----------------------------------------------------------------------------- +enum FirmwareCommand { + EnterBootloader = 0x42, NoOperation = 0x5A, FirmwareVersion = 0x76, + + SetVdd = 0xA0, SetVpp = 0xA1, ReadStatus = 0xA2, ReadVoltages = 0xA3, + DownloadScript = 0xA4, RunScript = 0xA5, ExecuteScript = 0xA6, + ClearDownloadBuffer = 0xA7, DownloadData = 0xA8, ClearUploadBuffer = 0xA9, + UploadData = 0xAA, ClearScriptBuffer = 0xAB, UploadDataNoLen = 0xAC, + EndOfBuffer = 0xAD, Reset = 0xAE, ScriptBufferChecksum = 0xAF, + + SetVoltageCalibrations = 0xB0, WriteInternalEEprom = 0xB1, + ReadInternalEEprom = 0xB2, EnterUARTMode = 0xB3, ExitUARTMode = 0xB4 +}; + +enum ScriptCommand { + VddOn = 0xFF, VddOff = 0xFE, VddGroundOn = 0xFD, VddGroundOff = 0xFC, + VppOn = 0xFB, VppOff = 0xFA, VppPwmOn = 0xF9, VppPwmOff = 0xF8, + MclrGroundOn = 0xF7, MclrGroundOff = 0xF6, BusyLedOn = 0xF5, BusyLedOff = 0xF4, + SetIcspPins = 0xF3, WriteByteLiteral = 0xF2, WriteByteBuffer = 0xF1, + ReadByteBuffer = 0xF0, ReadByte = 0xEF, WriteBitsLiteral = 0xEE, + WriteBitsBuffer = 0xED, ReadBitsBuffer = 0xEC, ReadBits = 0xEB, + SetIcspSpeed = 0xEA, Loop = 0xE9, DelayLong = 0xE8, DelayShort = 0xE7, + IfEqGoto = 0xE6, IfGtGoto = 0xE5, GotoIndex = 0xE4, ExitScript = 0xE3, + + PeekSfr = 0xE2, PokeSfr = 0xE1, IcdSlaveRx = 0xE0, IcdSlaveTxLiteral = 0xDF, + IcdSlaveTxBuffer = 0xDE, LoopBuffer = 0xDD, IcspStatesBuffer = 0xDC, + PopDownload = 0xDB, CoreInst18 = 0xDA, CoreInst24 = 0xD9, Nop24 = 0xD8, + Visi24 = 0xD7, Rd2ByteBuffer = 0xD6, Rd2BitsBuffer = 0xD5, WriteBufWordW = 0xD4, + WriteBufByteW = 0xD3, ConstWriteDl = 0xD2, WriteBitsLitHld = 0xD1, + WriteBitsBufHld = 0xD0, SetAux = 0xCF, AuxStateBuffer = 0xCE, I2cStart = 0xCD, + I2cStop = 0xCC, I2cWriteByteLiteral = 0xCB, I2cWriteByteBuffer = 0xCA, + I2cReadByteAck = 0xC9, I2cReadByteNack = 0xC8, SpiWriteByteLiteral = 0xC7, + SpiWriteByteBuffer = 0xC6, SpiReadByteBuffer = 0xC5, SpiReadWriteByteLiteral = 0xC4, + SpiReadWriteByteBuffer = 0xC3 +}; +extern const FamilyData *familyData(const Pic::Data &device); + +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(64, EndOfBuffer, PrintEscapeAll) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit2::USBPort +{ +public: + USBPort(Log::Base &manager) : Pickit2::USBPort(manager) {} + virtual Pickit::Array array() const { return Array(); } +}; + +enum StatusFlag { + DownloadBufferOverflow = 0x8000, ScriptBufferOverflow = 0x4000, + RunScriptOnEmptyScript = 0x2000, ScriptAbortDownloadEmpty = 0x1000, + ScriptAbortUploadFull = 0x0800, IcdTransferTimeout = 0x0400, + UARTModeEnabled = 0x0200, ResetSinceLastStatusRead = 0x0100, + ButtonPressed = 0x0040, VppError = 0x0020, VddError = 0x0010, + VppIsOn = 0x0008, VppGroundIsOn = 0x0004, + VddIsOn = 0x0002, VddGroundIsOn = 0x0001 }; +Q_DECLARE_FLAGS(StatusFlags, StatusFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(StatusFlags) + +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base); + USBPort &port() { return static_cast<USBPort &>(*_port); } + const USBPort &port() const { return static_cast<USBPort &>(*_port); } + + bool getMode(VersionData &version, ::Programmer::Mode &mode); + bool setTargetReset(Pic::ResetMode mode); + bool setVddVoltage(double value, double threshold); + bool setVppVoltage(double value, double threshold); + bool setVddOn(bool on); + bool executeScript(uint i); + bool setTarget(); + bool setFastProgramming(bool fast); + virtual bool readVoltages(VoltagesData &voltagesData); + bool readStatus(ushort &status); + bool readMemory(Pic::MemoryRangeType type, ::Device::Array &data, const ::Programmer::VerifyData *vdata); + bool writeMemory(Pic::MemoryRangeType type, const ::Device::Array &data, bool force); + bool eraseAll(); + bool eraseRange(Pic::MemoryRangeType type); + +private: + enum { UploadBufferNbBytes = 128, DownloadBufferNbBytes = 256 }; + uint _scriptBufferChecksum; + bool _deviceSet, _fastProgramming; + + virtual bool internalConnectHardware(); + bool getScriptBufferChecksum(uint &checksum); + bool downloadScript(ScriptType type, uint i); + bool downloadScripts(); + bool sendScript(const ushort *script, uint length); + bool resetPickit2() { return port().command(Reset); } + bool setIcspSpeed(uchar speed); + bool downloadAddress(Address address); + bool runScript(ScriptType stype, uint repetitions = 1, uint nbNoLens = 0); + bool prepareRead(Pic::MemoryRangeType type, uint wordIndex); + bool prepareWrite(Pic::MemoryRangeType type, uint wordIndex); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const; + virtual bool canReadRange(Pic::MemoryRangeType) const; + virtual bool canWriteRange(Pic::MemoryRangeType) const; + Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + virtual bool setPowerOn() { return true; } + virtual bool setPowerOff() { return true; } + virtual bool setTargetPowerOn(bool on) { return hardware().setVddOn(on); } + virtual bool doErase(bool) { return hardware().eraseAll(); } + virtual bool doEraseRange(Pic::MemoryRangeType type) { return hardware().eraseRange(type); } + virtual bool doRead(Pic::MemoryRangeType type, ::Device::Array &data, const ::Programmer::VerifyData *vdata) { + return hardware().readMemory(type, data, vdata); + } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/base/pickit2v2_data.cpp b/src/progs/pickit2v2/base/pickit2v2_data.cpp new file mode 100644 index 0000000..b93fad4 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_data.cpp @@ -0,0 +1,951 @@ +// this file is autogenerated, do not edit ! + +#include "devices/list/device_list.h" +#include "pickit2v2_prog.h" +#include "pickit2v2_data.h" + +namespace Pickit2V2 +{ +struct CData { + const char *name; + Data data; +}; + +const CData PIC10F200_DATA = { "10F200", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F202_DATA = { "10F202", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F204_DATA = { "10F204", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F206_DATA = { "10F206", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F220_DATA = { "10F220", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F222_DATA = { "10F222", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F508_DATA = { "12F508", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F509_DATA = { "12F509", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F510_DATA = { "12F510", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F519_DATA = { "12F519", { 32, 32, 1, 1, + { 1, 2, 0, 36, 0, 31, 0, 40, 167, 36, 167, 40, 0, 37, 0, 43, 0, 162, 0, 163, 164, 165, 166, 168, 169, 0, 0, 134, 0 } } }; +const CData PIC12F609_DATA = { "12F609", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12F615_DATA = { "12F615", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12F629_DATA = { "12F629", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC12F635_DATA = { "12F635", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC12F675_DATA = { "12F675", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC12F683_DATA = { "12F683", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC12HV609_DATA = { "12HV609", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12HV615_DATA = { "12HV615", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F505_DATA = { "16F505", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F506_DATA = { "16F506", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F526_DATA = { "16F526", { 32, 32, 1, 1, + { 1, 2, 0, 36, 0, 31, 0, 40, 167, 36, 167, 40, 0, 37, 0, 43, 0, 162, 0, 163, 164, 165, 166, 168, 169, 0, 0, 134, 0 } } }; +const CData PIC16F54_DATA = { "16F54", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 0, 0, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F57_DATA = { "16F57", { 32, 0, 4, 0, + { 1, 2, 0, 36, 0, 31, 0, 53, 0, 0, 0, 0, 0, 37, 0, 43, 0, 52, 0, 51, 0, 0, 41, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F59_DATA = { "16F59", { 32, 0, 4, 0, + { 1, 2, 0, 36, 0, 31, 0, 53, 0, 0, 0, 0, 0, 37, 0, 43, 0, 52, 0, 51, 0, 0, 41, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F610_DATA = { "16F610", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F616_DATA = { "16F616", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 0, 0, 78, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F627_DATA = { "16F627", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 126, 0, 0, 0, 132, 0 } } }; +const CData PIC16F627A_DATA = { "16F627A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F628_DATA = { "16F628", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 126, 0, 0, 0, 132, 0 } } }; +const CData PIC16F628A_DATA = { "16F628A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F630_DATA = { "16F630", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F631_DATA = { "16F631", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F636_DATA = { "16F636", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F639_DATA = { "16F639", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F648A_DATA = { "16F648A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F676_DATA = { "16F676", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F677_DATA = { "16F677", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F684_DATA = { "16F684", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F685_DATA = { "16F685", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F687_DATA = { "16F687", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F688_DATA = { "16F688", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F689_DATA = { "16F689", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F690_DATA = { "16F690", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F716_DATA = { "16F716", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 31, 0, 118, 0, 0, 0, 0, 0, 8, 0, 120, 0, 7, 0, 119, 0, 0, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F72_DATA = { "16F72", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F73_DATA = { "16F73", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F737_DATA = { "16F737", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F74_DATA = { "16F74", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F747_DATA = { "16F747", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F76_DATA = { "16F76", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F767_DATA = { "16F767", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F77_DATA = { "16F77", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F777_DATA = { "16F777", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F785_DATA = { "16F785", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F818_DATA = { "16F818", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 91, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F819_DATA = { "16F819", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 91, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F84A_DATA = { "16F84A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F87_DATA = { "16F87", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 89, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F870_DATA = { "16F870", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F871_DATA = { "16F871", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F872_DATA = { "16F872", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F873_DATA = { "16F873", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F873A_DATA = { "16F873A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F874_DATA = { "16F874", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F874A_DATA = { "16F874A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F876_DATA = { "16F876", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F876A_DATA = { "16F876A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F877_DATA = { "16F877", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F877A_DATA = { "16F877A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F88_DATA = { "16F88", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 89, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F882_DATA = { "16F882", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F883_DATA = { "16F883", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F884_DATA = { "16F884", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F886_DATA = { "16F886", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 32, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F887_DATA = { "16F887", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 32, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F913_DATA = { "16F913", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F914_DATA = { "16F914", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F916_DATA = { "16F916", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F917_DATA = { "16F917", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F946_DATA = { "16F946", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16HV610_DATA = { "16HV610", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16HV616_DATA = { "16HV616", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 0, 0, 78, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16HV785_DATA = { "16HV785", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC18F1220_DATA = { "18F1220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F1230_DATA = { "18F1230", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F1320_DATA = { "18F1320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F1330_DATA = { "18F1330", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2220_DATA = { "18F2220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2221_DATA = { "18F2221", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2320_DATA = { "18F2320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2321_DATA = { "18F2321", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2331_DATA = { "18F2331", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2410_DATA = { "18F2410", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F242_DATA = { "18F242", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2420_DATA = { "18F2420", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2423_DATA = { "18F2423", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2431_DATA = { "18F2431", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2450_DATA = { "18F2450", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 94, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2455_DATA = { "18F2455", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2458_DATA = { "18F2458", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F248_DATA = { "18F248", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2480_DATA = { "18F2480", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F24J10_DATA = { "18F24J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F24K20_DATA = { "18F24K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2510_DATA = { "18F2510", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2515_DATA = { "18F2515", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F252_DATA = { "18F252", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2520_DATA = { "18F2520", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2523_DATA = { "18F2523", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2525_DATA = { "18F2525", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2550_DATA = { "18F2550", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2553_DATA = { "18F2553", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F258_DATA = { "18F258", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2580_DATA = { "18F2580", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2585_DATA = { "18F2585", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F25J10_DATA = { "18F25J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F25K20_DATA = { "18F25K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2610_DATA = { "18F2610", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2620_DATA = { "18F2620", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2680_DATA = { "18F2680", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2682_DATA = { "18F2682", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2685_DATA = { "18F2685", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4220_DATA = { "18F4220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4221_DATA = { "18F4221", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4320_DATA = { "18F4320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4321_DATA = { "18F4321", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4331_DATA = { "18F4331", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4410_DATA = { "18F4410", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F442_DATA = { "18F442", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4420_DATA = { "18F4420", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4423_DATA = { "18F4423", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4431_DATA = { "18F4431", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4450_DATA = { "18F4450", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 94, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4455_DATA = { "18F4455", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4458_DATA = { "18F4458", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F448_DATA = { "18F448", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4480_DATA = { "18F4480", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F44J10_DATA = { "18F44J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F44K20_DATA = { "18F44K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4510_DATA = { "18F4510", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4515_DATA = { "18F4515", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F452_DATA = { "18F452", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4520_DATA = { "18F4520", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4523_DATA = { "18F4523", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4525_DATA = { "18F4525", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4550_DATA = { "18F4550", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4553_DATA = { "18F4553", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F458_DATA = { "18F458", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4580_DATA = { "18F4580", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4585_DATA = { "18F4585", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F45J10_DATA = { "18F45J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F45K20_DATA = { "18F45K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4610_DATA = { "18F4610", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4620_DATA = { "18F4620", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4680_DATA = { "18F4680", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4682_DATA = { "18F4682", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4685_DATA = { "18F4685", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6310_DATA = { "18F6310", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6390_DATA = { "18F6390", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F63J11_DATA = { "18F63J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F63J90_DATA = { "18F63J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6410_DATA = { "18F6410", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6490_DATA = { "18F6490", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F64J11_DATA = { "18F64J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F64J90_DATA = { "18F64J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6520_DATA = { "18F6520", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6525_DATA = { "18F6525", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6527_DATA = { "18F6527", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6585_DATA = { "18F6585", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F65J10_DATA = { "18F65J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J11_DATA = { "18F65J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J15_DATA = { "18F65J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J50_DATA = { "18F65J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J90_DATA = { "18F65J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6620_DATA = { "18F6620", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6621_DATA = { "18F6621", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6622_DATA = { "18F6622", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6627_DATA = { "18F6627", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6628_DATA = { "18F6628", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6680_DATA = { "18F6680", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F66J10_DATA = { "18F66J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J11_DATA = { "18F66J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J15_DATA = { "18F66J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J16_DATA = { "18F66J16", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J50_DATA = { "18F66J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J55_DATA = { "18F66J55", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J60_DATA = { "18F66J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J65_DATA = { "18F66J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6720_DATA = { "18F6720", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6722_DATA = { "18F6722", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6723_DATA = { "18F6723", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F67J10_DATA = { "18F67J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J11_DATA = { "18F67J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J50_DATA = { "18F67J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J60_DATA = { "18F67J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8310_DATA = { "18F8310", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F8390_DATA = { "18F8390", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F83J11_DATA = { "18F83J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F83J90_DATA = { "18F83J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8410_DATA = { "18F8410", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F8490_DATA = { "18F8490", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F84J11_DATA = { "18F84J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F84J90_DATA = { "18F84J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8520_DATA = { "18F8520", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8525_DATA = { "18F8525", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8527_DATA = { "18F8527", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8585_DATA = { "18F8585", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F85J10_DATA = { "18F85J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J11_DATA = { "18F85J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J15_DATA = { "18F85J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J50_DATA = { "18F85J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J90_DATA = { "18F85J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8620_DATA = { "18F8620", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8621_DATA = { "18F8621", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8622_DATA = { "18F8622", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8627_DATA = { "18F8627", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8628_DATA = { "18F8628", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8680_DATA = { "18F8680", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F86J10_DATA = { "18F86J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J11_DATA = { "18F86J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J15_DATA = { "18F86J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J16_DATA = { "18F86J16", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J50_DATA = { "18F86J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J55_DATA = { "18F86J55", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J60_DATA = { "18F86J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J65_DATA = { "18F86J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8720_DATA = { "18F8720", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8722_DATA = { "18F8722", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8723_DATA = { "18F8723", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F87J10_DATA = { "18F87J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J11_DATA = { "18F87J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J50_DATA = { "18F87J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J60_DATA = { "18F87J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F96J60_DATA = { "18F96J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F96J65_DATA = { "18F96J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F97J60_DATA = { "18F97J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF24J10_DATA = { "18LF24J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF25J10_DATA = { "18LF25J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF44J10_DATA = { "18LF44J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF45J10_DATA = { "18LF45J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA006_DATA = { "24FJ128GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA008_DATA = { "24FJ128GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA010_DATA = { "24FJ128GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ16GA002_DATA = { "24FJ16GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ16GA004_DATA = { "24FJ16GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ32GA002_DATA = { "24FJ32GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ32GA004_DATA = { "24FJ32GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ48GA002_DATA = { "24FJ48GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ48GA004_DATA = { "24FJ48GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA002_DATA = { "24FJ64GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA004_DATA = { "24FJ64GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA006_DATA = { "24FJ64GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA008_DATA = { "24FJ64GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA010_DATA = { "24FJ64GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA006_DATA = { "24FJ96GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA008_DATA = { "24FJ96GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA010_DATA = { "24FJ96GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP206_DATA = { "24HJ128GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP210_DATA = { "24HJ128GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP306_DATA = { "24HJ128GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP310_DATA = { "24HJ128GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP506_DATA = { "24HJ128GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP510_DATA = { "24HJ128GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ12GP201_DATA = { "24HJ12GP201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ12GP202_DATA = { "24HJ12GP202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP206_DATA = { "24HJ256GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP210_DATA = { "24HJ256GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP610_DATA = { "24HJ256GP610", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP206_DATA = { "24HJ64GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP210_DATA = { "24HJ64GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP506_DATA = { "24HJ64GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP510_DATA = { "24HJ64GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F1010_DATA = { "30F1010", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F2010_DATA = { "30F2010", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F2011_DATA = { "30F2011", { 42, 0, 32, 0, + { 1, 2, 140, 143, 112, 142, 146, 147, 0, 0, 0, 0, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 0 } } }; +const CData PIC30F2012_DATA = { "30F2012", { 42, 0, 32, 0, + { 1, 2, 140, 143, 112, 142, 146, 147, 0, 0, 0, 0, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 0 } } }; +const CData PIC30F2020_DATA = { "30F2020", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F2023_DATA = { "30F2023", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F3010_DATA = { "30F3010", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3011_DATA = { "30F3011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3012_DATA = { "30F3012", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3013_DATA = { "30F3013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3014_DATA = { "30F3014", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4011_DATA = { "30F4011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4012_DATA = { "30F4012", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4013_DATA = { "30F4013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F5011_DATA = { "30F5011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 152, 0, 0, 0 } } }; +const CData PIC30F5013_DATA = { "30F5013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 152, 0, 0, 0 } } }; +const CData PIC30F5015_DATA = { "30F5015", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F5016_DATA = { "30F5016", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6010A_DATA = { "30F6010A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6011A_DATA = { "30F6011A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6012A_DATA = { "30F6012A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6013A_DATA = { "30F6013A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6014A_DATA = { "30F6014A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6015_DATA = { "30F6015", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC33FJ128GP206_DATA = { "33FJ128GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP306_DATA = { "33FJ128GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP310_DATA = { "33FJ128GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP706_DATA = { "33FJ128GP706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP708_DATA = { "33FJ128GP708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP710_DATA = { "33FJ128GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC506_DATA = { "33FJ128MC506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC510_DATA = { "33FJ128MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC706_DATA = { "33FJ128MC706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC708_DATA = { "33FJ128MC708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC710_DATA = { "33FJ128MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12GP201_DATA = { "33FJ12GP201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12GP202_DATA = { "33FJ12GP202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12MC201_DATA = { "33FJ12MC201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12MC202_DATA = { "33FJ12MC202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP506_DATA = { "33FJ256GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP510_DATA = { "33FJ256GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP710_DATA = { "33FJ256GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256MC510_DATA = { "33FJ256MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256MC710_DATA = { "33FJ256MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP206_DATA = { "33FJ64GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP306_DATA = { "33FJ64GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP310_DATA = { "33FJ64GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP706_DATA = { "33FJ64GP706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP708_DATA = { "33FJ64GP708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP710_DATA = { "33FJ64GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC506_DATA = { "33FJ64MC506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC508_DATA = { "33FJ64MC508", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC510_DATA = { "33FJ64MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC706_DATA = { "33FJ64MC706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC710_DATA = { "33FJ64MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; + +const CData *DATA_LIST[] = { +&PIC10F200_DATA,&PIC10F202_DATA,&PIC10F204_DATA,&PIC10F206_DATA,&PIC10F220_DATA,&PIC10F222_DATA,&PIC12F508_DATA,&PIC12F509_DATA,&PIC12F510_DATA,&PIC12F519_DATA,&PIC12F609_DATA,&PIC12F615_DATA,&PIC12F629_DATA,&PIC12F635_DATA,&PIC12F675_DATA,&PIC12F683_DATA,&PIC12HV609_DATA,&PIC12HV615_DATA,&PIC16F505_DATA,&PIC16F506_DATA, +&PIC16F526_DATA,&PIC16F54_DATA,&PIC16F57_DATA,&PIC16F59_DATA,&PIC16F610_DATA,&PIC16F616_DATA,&PIC16F627_DATA,&PIC16F627A_DATA,&PIC16F628_DATA,&PIC16F628A_DATA,&PIC16F630_DATA,&PIC16F631_DATA,&PIC16F636_DATA,&PIC16F639_DATA,&PIC16F648A_DATA,&PIC16F676_DATA,&PIC16F677_DATA,&PIC16F684_DATA,&PIC16F685_DATA,&PIC16F687_DATA, +&PIC16F688_DATA,&PIC16F689_DATA,&PIC16F690_DATA,&PIC16F716_DATA,&PIC16F72_DATA,&PIC16F73_DATA,&PIC16F737_DATA,&PIC16F74_DATA,&PIC16F747_DATA,&PIC16F76_DATA,&PIC16F767_DATA,&PIC16F77_DATA,&PIC16F777_DATA,&PIC16F785_DATA,&PIC16F818_DATA,&PIC16F819_DATA,&PIC16F84A_DATA,&PIC16F87_DATA,&PIC16F870_DATA,&PIC16F871_DATA, +&PIC16F872_DATA,&PIC16F873_DATA,&PIC16F873A_DATA,&PIC16F874_DATA,&PIC16F874A_DATA,&PIC16F876_DATA,&PIC16F876A_DATA,&PIC16F877_DATA,&PIC16F877A_DATA,&PIC16F88_DATA,&PIC16F882_DATA,&PIC16F883_DATA,&PIC16F884_DATA,&PIC16F886_DATA,&PIC16F887_DATA,&PIC16F913_DATA,&PIC16F914_DATA,&PIC16F916_DATA,&PIC16F917_DATA,&PIC16F946_DATA, +&PIC16HV610_DATA,&PIC16HV616_DATA,&PIC16HV785_DATA,&PIC18F1220_DATA,&PIC18F1230_DATA,&PIC18F1320_DATA,&PIC18F1330_DATA,&PIC18F2220_DATA,&PIC18F2221_DATA,&PIC18F2320_DATA,&PIC18F2321_DATA,&PIC18F2331_DATA,&PIC18F2410_DATA,&PIC18F242_DATA,&PIC18F2420_DATA,&PIC18F2423_DATA,&PIC18F2431_DATA,&PIC18F2450_DATA,&PIC18F2455_DATA,&PIC18F2458_DATA, +&PIC18F248_DATA,&PIC18F2480_DATA,&PIC18F24J10_DATA,&PIC18F24K20_DATA,&PIC18F2510_DATA,&PIC18F2515_DATA,&PIC18F252_DATA,&PIC18F2520_DATA,&PIC18F2523_DATA,&PIC18F2525_DATA,&PIC18F2550_DATA,&PIC18F2553_DATA,&PIC18F258_DATA,&PIC18F2580_DATA,&PIC18F2585_DATA,&PIC18F25J10_DATA,&PIC18F25K20_DATA,&PIC18F2610_DATA,&PIC18F2620_DATA,&PIC18F2680_DATA, +&PIC18F2682_DATA,&PIC18F2685_DATA,&PIC18F4220_DATA,&PIC18F4221_DATA,&PIC18F4320_DATA,&PIC18F4321_DATA,&PIC18F4331_DATA,&PIC18F4410_DATA,&PIC18F442_DATA,&PIC18F4420_DATA,&PIC18F4423_DATA,&PIC18F4431_DATA,&PIC18F4450_DATA,&PIC18F4455_DATA,&PIC18F4458_DATA,&PIC18F448_DATA,&PIC18F4480_DATA,&PIC18F44J10_DATA,&PIC18F44K20_DATA,&PIC18F4510_DATA, +&PIC18F4515_DATA,&PIC18F452_DATA,&PIC18F4520_DATA,&PIC18F4523_DATA,&PIC18F4525_DATA,&PIC18F4550_DATA,&PIC18F4553_DATA,&PIC18F458_DATA,&PIC18F4580_DATA,&PIC18F4585_DATA,&PIC18F45J10_DATA,&PIC18F45K20_DATA,&PIC18F4610_DATA,&PIC18F4620_DATA,&PIC18F4680_DATA,&PIC18F4682_DATA,&PIC18F4685_DATA,&PIC18F6310_DATA,&PIC18F6390_DATA,&PIC18F63J11_DATA, +&PIC18F63J90_DATA,&PIC18F6410_DATA,&PIC18F6490_DATA,&PIC18F64J11_DATA,&PIC18F64J90_DATA,&PIC18F6520_DATA,&PIC18F6525_DATA,&PIC18F6527_DATA,&PIC18F6585_DATA,&PIC18F65J10_DATA,&PIC18F65J11_DATA,&PIC18F65J15_DATA,&PIC18F65J50_DATA,&PIC18F65J90_DATA,&PIC18F6620_DATA,&PIC18F6621_DATA,&PIC18F6622_DATA,&PIC18F6627_DATA,&PIC18F6628_DATA,&PIC18F6680_DATA, +&PIC18F66J10_DATA,&PIC18F66J11_DATA,&PIC18F66J15_DATA,&PIC18F66J16_DATA,&PIC18F66J50_DATA,&PIC18F66J55_DATA,&PIC18F66J60_DATA,&PIC18F66J65_DATA,&PIC18F6720_DATA,&PIC18F6722_DATA,&PIC18F6723_DATA,&PIC18F67J10_DATA,&PIC18F67J11_DATA,&PIC18F67J50_DATA,&PIC18F67J60_DATA,&PIC18F8310_DATA,&PIC18F8390_DATA,&PIC18F83J11_DATA,&PIC18F83J90_DATA,&PIC18F8410_DATA, +&PIC18F8490_DATA,&PIC18F84J11_DATA,&PIC18F84J90_DATA,&PIC18F8520_DATA,&PIC18F8525_DATA,&PIC18F8527_DATA,&PIC18F8585_DATA,&PIC18F85J10_DATA,&PIC18F85J11_DATA,&PIC18F85J15_DATA,&PIC18F85J50_DATA,&PIC18F85J90_DATA,&PIC18F8620_DATA,&PIC18F8621_DATA,&PIC18F8622_DATA,&PIC18F8627_DATA,&PIC18F8628_DATA,&PIC18F8680_DATA,&PIC18F86J10_DATA,&PIC18F86J11_DATA, +&PIC18F86J15_DATA,&PIC18F86J16_DATA,&PIC18F86J50_DATA,&PIC18F86J55_DATA,&PIC18F86J60_DATA,&PIC18F86J65_DATA,&PIC18F8720_DATA,&PIC18F8722_DATA,&PIC18F8723_DATA,&PIC18F87J10_DATA,&PIC18F87J11_DATA,&PIC18F87J50_DATA,&PIC18F87J60_DATA,&PIC18F96J60_DATA,&PIC18F96J65_DATA,&PIC18F97J60_DATA,&PIC18LF24J10_DATA,&PIC18LF25J10_DATA,&PIC18LF44J10_DATA,&PIC18LF45J10_DATA, +&PIC24FJ128GA006_DATA,&PIC24FJ128GA008_DATA,&PIC24FJ128GA010_DATA,&PIC24FJ16GA002_DATA,&PIC24FJ16GA004_DATA,&PIC24FJ32GA002_DATA,&PIC24FJ32GA004_DATA,&PIC24FJ48GA002_DATA,&PIC24FJ48GA004_DATA,&PIC24FJ64GA002_DATA,&PIC24FJ64GA004_DATA,&PIC24FJ64GA006_DATA,&PIC24FJ64GA008_DATA,&PIC24FJ64GA010_DATA,&PIC24FJ96GA006_DATA,&PIC24FJ96GA008_DATA,&PIC24FJ96GA010_DATA,&PIC24HJ128GP206_DATA,&PIC24HJ128GP210_DATA,&PIC24HJ128GP306_DATA, +&PIC24HJ128GP310_DATA,&PIC24HJ128GP506_DATA,&PIC24HJ128GP510_DATA,&PIC24HJ12GP201_DATA,&PIC24HJ12GP202_DATA,&PIC24HJ256GP206_DATA,&PIC24HJ256GP210_DATA,&PIC24HJ256GP610_DATA,&PIC24HJ64GP206_DATA,&PIC24HJ64GP210_DATA,&PIC24HJ64GP506_DATA,&PIC24HJ64GP510_DATA,&PIC30F1010_DATA,&PIC30F2010_DATA,&PIC30F2011_DATA,&PIC30F2012_DATA,&PIC30F2020_DATA,&PIC30F2023_DATA,&PIC30F3010_DATA,&PIC30F3011_DATA, +&PIC30F3012_DATA,&PIC30F3013_DATA,&PIC30F3014_DATA,&PIC30F4011_DATA,&PIC30F4012_DATA,&PIC30F4013_DATA,&PIC30F5011_DATA,&PIC30F5013_DATA,&PIC30F5015_DATA,&PIC30F5016_DATA,&PIC30F6010A_DATA,&PIC30F6011A_DATA,&PIC30F6012A_DATA,&PIC30F6013A_DATA,&PIC30F6014A_DATA,&PIC30F6015_DATA,&PIC33FJ128GP206_DATA,&PIC33FJ128GP306_DATA,&PIC33FJ128GP310_DATA,&PIC33FJ128GP706_DATA, +&PIC33FJ128GP708_DATA,&PIC33FJ128GP710_DATA,&PIC33FJ128MC506_DATA,&PIC33FJ128MC510_DATA,&PIC33FJ128MC706_DATA,&PIC33FJ128MC708_DATA,&PIC33FJ128MC710_DATA,&PIC33FJ12GP201_DATA,&PIC33FJ12GP202_DATA,&PIC33FJ12MC201_DATA,&PIC33FJ12MC202_DATA,&PIC33FJ256GP506_DATA,&PIC33FJ256GP510_DATA,&PIC33FJ256GP710_DATA,&PIC33FJ256MC510_DATA,&PIC33FJ256MC710_DATA,&PIC33FJ64GP206_DATA,&PIC33FJ64GP306_DATA,&PIC33FJ64GP310_DATA,&PIC33FJ64GP706_DATA, +&PIC33FJ64GP708_DATA,&PIC33FJ64GP710_DATA,&PIC33FJ64MC506_DATA,&PIC33FJ64MC508_DATA,&PIC33FJ64MC510_DATA,&PIC33FJ64MC706_DATA,&PIC33FJ64MC710_DATA,0 +}; + +const CData *cdata(const QString &device) +{ +for(uint i=0; DATA_LIST[i]; i++) + if ( device==DATA_LIST[i]->name ) return DATA_LIST[i]; +return 0; +} +::Group::Support support(const QString &) +{ + return ::Group::Support::Untested; +} +const Data &data(const QString &device) +{ + return cdata(device)->data; +} +void Group::initSupported() +{ + for (uint i=0; DATA_LIST[i]; i++) { + const Device::Data *data = Device::lister().data(DATA_LIST[i]->name); + if ( data==0 ) continue; + addDevice(data->name(), data, ::Group::Support::Untested); + } +} + +const FamilyData FAMILY_DATA[] = { + { Pic::Architecture::Type(1), 12, 0x0001, 0x0002, 0x0003, true }, + { Pic::Architecture::Type(0), 12, 0x0001, 0x0002, 0x0000, true }, + { Pic::Architecture::Type(4), 12, 0x0001, 0x0002, 0x0037, false }, + { Pic::Architecture::Nb_Types, 0.0, 0x0000, 0x0000, 0x0000, false } +}; + +const ScriptData SCRIPT_DATA[] = { + { "HVProgEntry1", 5, 18, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { "HVProgExit1", 4, 8, { 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF3, 0xBB03, 0xAAE8, 0x000A, 0xAAF4 } }, + { "MR_RdDevID1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB05, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_ChpEraseEE10msI", 0, 17, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB0B, 0xAAE8, 0xBB02 } }, + { "MR_ProgMemRd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0x001F } }, + { "MR_EERd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB05, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0x001F } }, + { "MR_UsrIDRd4.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB03 } }, + { "MR_CfgRd1.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_PrgMemWr8Int.1", 1, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_EEWr1Int.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB03, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0x0001, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.1", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgWr1Int.1", 0, 16, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_PrgMemWr4Int.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB06 } }, + { "DBG_Halt.1", 1, 10, { 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0x0005, 0xAAF3, 0xBB01 } }, + { "DBG_RdDEVer.1", 1, 11, { 0xAAF5, 0xAADF, 0xBB02, 0xAAE0, 0xAAE6, 0xBB00, 0xBB05, 0xAAE0, 0xAAE0, 0xAAE0, 0xAAF4 } }, + { "DBG_Run.1", 1, 10, { 0xAAF5, 0xAADF, 0xBB19, 0xAAE0, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAE0 } }, + { "DBG_BulkWrData.1", 1, 18, { 0xAAF5, 0xAADF, 0xBB04, 0xAAE0, 0xAAE6, 0xBB00, 0x000C, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAE0, 0xAAF4 } }, + { "DBG_BulkRdData.1", 1, 18, { 0xAAF5, 0xAADF, 0xBB03, 0xAAE0, 0xAAE6, 0xBB00, 0x000C, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAAE0, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAE0, 0xAAF4 } }, + { "DBG_SStep.1", 1, 10, { 0xAAF5, 0xAADF, 0xBB1A, 0xAAE0, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAE0 } }, + { "DBG_Status.1", 0, 1, { 0xAADC } }, + { "24_ProgEntry.1", 1, 31, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB, 0xAAFA, 0xAAF7, 0xAAE7, 0x002F, 0xAAF2, 0xBBB2, 0xAAF2, 0xBBC2, 0xAAF2, 0xBB12, 0xAAF2, 0xBB8A, 0xAAF6, 0xAAFB, 0xAAE8, 0x0009, 0xAAEE, 0xBB05, 0xBB00 } }, + { "24_RdDevID.1", 0, 47, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBBF0, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAD7, 0xAAD8 } }, + { "24_SetAddr.1", 0, 29, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD4, 0xBB06, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "24_ProgMemRd42.1", 0, 28, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD7, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAD6, 0xAAEF, 0xAAE9, 0x0014, 0x0029, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "24_ChpErase450ms.1", 0, 39, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBBFA, 0xBB04, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0xBB00, 0xAAE8, 0x0050 } }, + { "24_ProgMemWrPrep.1", 0, 33, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "24_ProgMemWr64.1", 0, 50, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD4, 0xBB03, 0xAAD3, 0xBB02, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB82, 0xBB8B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB83, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0020, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0x0003, 0xAAE7, 0xBC64 } }, + { "MR_ProgMemWr1Int.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_RdOSCCAL.1", 0, 13, { 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_WrOSCCALInt.1", 0, 18, { 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076 } }, + { "MR_AddrSet.1", 0, 16, { 0xAAFA, 0xAAF7, 0xAAE7, 0x005E, 0xAAF6, 0xAAFB, 0xAAE7, 0x002F, 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB } }, + { "MR_PrgMemWr8Int.2", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgRd2.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB01 } }, + { "MR_CfgWr2Int.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "BL_PrgMemRd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0x001F } }, + { "BL_CfgRd1.1", 0, 5, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_UsrIDRd4@x400", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_OSCCALRd1.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_PrgMemWr1Ext.1", 0, 16, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x800", 0, 38, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_UsrIDWr4Ext@x400", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_CfgWr1Ext", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_OSCCALWrExt", 0, 19, { 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x100", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_ChpErase@x200", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_UsrIDRd4@x100", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDRd4@x200", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x100", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x200", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x800", 0, 51, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0x0006, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDRd4@x800", 0, 41, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_PrgMemWr4Ext.1", 0, 19, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB03, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x400", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "18F_DevIDRd.1", 1, 30, { 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB3F, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBFF, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBFE, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0xBB01 } }, + { "18F_PrgMemRd64", 0, 9, { 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0x0006, 0x007F } }, + { "18F_SetAddr.1", 0, 27, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E } }, + { "18F_EERdPrepSmall.1", 0, 17, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADB, 0xAADB, 0xAADA, 0xBBA9, 0xBB6E } }, + { "18F_EERd32Small.1", 0, 21, { 0xAADA, 0xBBA6, 0xBB80, 0xAADA, 0xBBA8, 0xBB50, 0xAADA, 0xBBF5, 0xBB6E, 0xAAEE, 0xBB04, 0xBB02, 0xAAF2, 0xBB00, 0xAAF0, 0xAADA, 0xBBA9, 0xBB2A, 0xAAE9, 0x0012, 0x001F } }, + { "18F_CfgRd7.1", 0, 27, { 0xAADA, 0xBB30, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x000D } }, + { "18F_UsrIDRd4.1", 0, 27, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x0007 } }, + { "18F_ChpErase.x80", 0, 37, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB80, 0xAAF2, 0xBB80, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_PrgMemWrPrep.1", 0, 33, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C } }, + { "18F_ProgMemWr4.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_UsrIDWr4.1ms", 0, 47, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_CfgWrPrep", 0, 30, { 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB8C, 0xAADA, 0xBB00, 0xBBEF, 0xAADA, 0xBB00, 0xBBF8, 0xAADA, 0xBB30, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADB, 0xAADB, 0xAADB } }, + { "18F_CfgWr7_1ms", 0, 51, { 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF2, 0xBB00, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF2, 0xBB00, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAE9, 0x0030, 0x0006 } }, + { "18F_EEWrPrepSmall", 0, 17, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAADB, 0xAADB } }, + { "18F_EEWr1Small5ms", 0, 38, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA9, 0xBB2A } }, + { "18J_ProgEntry", 1, 28, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x002F, 0xAAFA, 0xAAF7, 0xAAE7, 0x002F, 0xAAF2, 0xBBB2, 0xAAF2, 0xBBC2, 0xAAF2, 0xBB12, 0xAAF2, 0xBB0A, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "18J_ChpErase400ms", 0, 52, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB01, 0xAAF2, 0xBB01, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB80, 0xAAF2, 0xBB80, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0x004A, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE8, 0xBB19 } }, + { "MR_CfgWr1Ext.1", 0, 21, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05 } }, + { "MR_DbgVctWr2Int.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0x0002, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB01 } }, + { "MR_DbgVctRd2.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB01 } }, + { "18J_PrgMemWrPrep", 0, 30, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84 } }, + { "18J_PrgMemWr32", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE8, 0x0001, 0xAAE7, 0x00D6, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "MR_ChpErase10ms", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "MR_PrgMemWr4Ext.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.1", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Int.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_PrgMemWr2Ext.1", 0, 26, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_ChpErase30ms", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB06 } }, + { "MR_UsrIDWr4Ext.2", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Ext.2", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05 } }, + { "MR_CfgWr2Ext.2", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "MR_ChpErase\"Chip\"1F", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB1F, 0xAAE8, 0xBB02 } }, + { "MR_PrgMemWr4Ext.2", 1, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.3", 1, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr2Ext.3", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "MR_EEWr1Ext.1", 2, 24, { 0xAAEE, 0xBB06, 0xBB03, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_CfgWr1Ext.3", 1, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005 } }, + { "MR_PrgMemWr8Ext.2", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "18F_ChpErase.x3F8F", 1, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB3F, 0xAAF2, 0xBB3F, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB8F, 0xAAF2, 0xBB8F, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr8.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB06, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_ChpErase.xFF87", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB87, 0xAAF2, 0xBB87, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr32.1ms-", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_EERdPrepLarge.1", 0, 31, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBAA, 0xBB6E, 0xAADB, 0xAADA, 0xBB99, 0xBB0E, 0xAADA, 0xBBF5, 0xBB6E } }, + { "18F_EERd32Large.1", 0, 33, { 0xAADA, 0xBBA6, 0xBB80, 0xAADA, 0xBBA8, 0xBB50, 0xAADA, 0xBBF5, 0xBB6E, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB02, 0xAAF2, 0xBB00, 0xAAF0, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A, 0xAAE9, 0x001E, 0x001F } }, + { "18F_EEWrPrepLarge.1", 0, 25, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBAA, 0xBB6E, 0xAADB } }, + { "18F_EEWr1Large5ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE9, 0xBB03, 0xBB03, 0xAAE8, 0x0001, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A } }, + { "MR_ChpErase87x", 0, 56, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB03, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07 } }, + { "MR_RowErase16.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB11, 0xAAE8, 0xBB01, 0xAAE7, 0x0019, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x000F } }, + { "18F_ProgMemWr16.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x000E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_ProgMemWr32.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "MR_ProgMemWr1Int.2", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.3", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgWr1Int.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC } }, + { "18F_EEWr1LargeAA55", 0, 44, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A } }, + { "MR_ProgMemWr1Ext.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_PMemErase10msI", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "MR_PMemEraseExt", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "30_ChpErasePrep", 0, 23, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88 } }, + { "MR_PMemErase87x", 0, 32, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAE8, 0xBB02 } }, + { "MR_EEMemEraseExt", 0, 11, { 0xAAEE, 0xBB06, 0xBB0B, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "18F_PMemErase.xF83", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB0F, 0xAAF2, 0xBB0F, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB83, 0xAAF2, 0xBB83, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_EraseTest2", 0, 43, { 0xBBD2, 0xBB83, 0xBBD2, 0xBB88, 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF1, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE9, 0x0024, 0xBB01 } }, + { "18F_PMemErase.xFF83", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB83, 0xAAF2, 0xBB83, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "MR_PrgMemWr4Ext.3", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.4", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Ext.4", 1, 27, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0x0001 } }, + { "33_CfgRd8", 0, 48, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB00, 0xBB03, 0xBBEB, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD7, 0xAAE9, 0xBB08, 0xBB07, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "33_UserIDRd4", 0, 54, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB01, 0xBB20, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAD6, 0xAAEF, 0xAAE9, 0x000D, 0xBB03, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "33_ProgMemWr64.1", 0, 50, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD4, 0xBB03, 0xAAD3, 0xBB02, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB82, 0xBB8B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB83, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0020, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0x0003, 0xAAE7, 0x0048 } }, + { "33_UsrIDWr4", 0, 60, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB07, 0xBB01, 0xBB20, 0xAAD9, 0xBB0A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD3, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAE8, 0xBB06, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAE9, 0x0015, 0xBB03 } }, + { "33_CfgWr8", 0, 60, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBB0A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAE8, 0x0006, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAE9, 0x0015, 0xBB07 } }, + { "MR_PMemErase15msI", 0, 15, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB09, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB03 } }, + { "MR_PrgMemWr4Int.2", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "18F_ChpErase.x018A", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB01, 0xAAF2, 0xBB01, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB8A, 0xAAF2, 0xBB8A, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB06, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr8.2ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x0006, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0xBB06, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_CfgWr7_2ms", 0, 60, { 0xAADA, 0xBBA6, 0xBB84, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF2, 0xBB00, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0x000C, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF2, 0xBB00, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0xBB12, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAE9, 0x0036, 0x0006 } }, + { "18F_UsrIDWr4.2ms", 0, 49, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB9C, 0xAADA, 0xBBA6, 0xBB84, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE7, 0xBB06 } }, + { "MR_TstMemRd8", 0, 11, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB07 } }, + { "30S_UsrIDRdPrep", 0, 33, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "BL_TestMemRd8", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0x0007 } }, + { "18F_TstMemRd8.1", 0, 9, { 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x000F } }, + { "MR_CalWrdsErWr91x", 0, 46, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdsErWr88x", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB08, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdsErWr6xx-1", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdErWr61x", 0, 33, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05 } }, + { "30_RdDevID", 0, 49, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAE9, 0xBB07, 0xBB01, 0xAAD9, 0xBBF0, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB03, 0xBBEB, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD8 } }, + { "30_ChpErase4ms", 0, 49, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBBFA, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x00BC, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8 } }, + { "30_SetAddr.1", 1, 35, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAE9, 0xBB07, 0xBB01, 0xAAD4, 0xBB06, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB20, 0xBB3B, 0xBB88, 0xAAD9, 0xBB05, 0xBB02, 0xBB20, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "30_ProgMemRd42.1", 0, 34, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAEF, 0xAAE9, 0x001A, 0x0029, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_CfgRd7", 0, 48, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB03, 0xBBEB, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD8, 0xAAE9, 0x0013, 0xBB06 } }, + { "30_EERd64.1", 0, 21, { 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAE9, 0x000D, 0x003F, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_ProgMemWrPrep.1", 1, 41, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8, 0xAAD9, 0xBB00, 0xBB03, 0xBBEB, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88, 0xAAD9, 0xBB05, 0xBB04, 0xBB20 } }, + { "30_ProgMemWr32.1", 0, 61, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x001F, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30_EEWrPrep.1", 0, 25, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB5A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30_EEWr16.1", 0, 61, { 0xAAD4, 0xBB00, 0xAAD4, 0xBB01, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x0007, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30_CfgWrPrep.1", 0, 28, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB8A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAADB, 0xAAD9, 0xBB81, 0xBB0F, 0xBB20, 0xAAD9, 0xBB91, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30_CfgWr7.1", 0, 53, { 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD8, 0xAAD8, 0xAAE9, 0x0032, 0x0006 } }, + { "30_CfgClear7.1", 0, 55, { 0xAAD9, 0xBB00, 0xBB00, 0xBB20, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD8, 0xAAD8, 0xAAE9, 0x0030, 0x0006 } }, + { "30_UsrIDRdPrep", 0, 25, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "30_UsrIDRd32.1", 0, 34, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAEF, 0xAAE9, 0x001A, 0x001F, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_UsrIDWrPrep.1", 0, 29, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB07, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30S_CfgWrPrep", 0, 27, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAADB, 0xAADB, 0xAADB, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBB8A, 0xBB00, 0xBB24 } }, + { "30S_CfgWr8", 0, 45, { 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE8, 0xBB01, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0x002A, 0xBB07 } }, + { "30S_ProgMemWr32", 0, 46, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0xBB94, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30S_ChpErasePrep", 0, 27, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88 } }, + { "30S_UsrIDWrPrep.1", 0, 32, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB07, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "MR_DbgVctWr2Ext.3", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "BL_UsrIDRd4@x440", 0, 32, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x440", 1, 42, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_OSCCALRd1@x3FF", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAADB, 0xAADB, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_OSCCALWrExt@x3FF", 0, 31, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAADB, 0xAADB, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase-519", 0, 45, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x000A, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000F, 0x00DA, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_EEPrep-x400", 0, 15, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF } }, + { "BL_PMemErase-519", 0, 28, { 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000F, 0x00DA, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_EEMemErase-519", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "18F_DbgVctWr2.2ms", 0, 49, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB28, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE7, 0xBB06 } }, + { "18F_DbgVctRd2.1", 0, 27, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB28, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x0003 } }, + { "MR_CfgRowErase.1", 0, 14, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB11, 0xAAE8, 0xBB01, 0xAAE7, 0x0019 } }, + { "MR_RowErase32.2", 0, 21, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x001F } }, + { "MR_CfgRowErase.2", 0, 15, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "18F_RowErase32.5ms.1", 0, 47, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA6, 0xBB94, 0xAADA, 0xBB40, 0xBB0E, 0xAADA, 0xBBF6, 0xBB26, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF7, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF8, 0xBB2A } }, + { "18F_UsrIDRowErs.5ms", 0, 29, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA6, 0xBB94 } }, + { "18F_RowErase32.5ms.2", 0, 50, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBBA6, 0xBB82, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0x0005, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB40, 0xBB0E, 0xAADA, 0xBBF6, 0xBB26, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF7, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF8, 0xBB2A, 0xAAE7, 0xBB47, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00 } }, + { "30_RowErase32.1", 0, 61, { 0xAAD9, 0xBB1A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB05, 0xBB03, 0xBB43, 0xAAD9, 0xBB42, 0xBB00, 0xBBAF, 0xAAD9, 0xBB64, 0xBB27, 0xBBEC, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88 } }, + { "30_UsrIDErase.1", 0, 61, { 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88, 0xAAD9, 0xBB1A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_EERowErase8.1", 0, 61, { 0xAAD9, 0xBB5A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB05, 0xBB03, 0xBB43, 0xAAD9, 0xBB42, 0xBB00, 0xBBAF, 0xAAD9, 0xBB64, 0xBB27, 0xBBEC, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88 } }, + { "MR_DbgVctWr2Ext.2", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "HVProgEntryVpp1st", 0, 22, { 0xAAFA, 0xAAF7, 0xAAFE, 0xAAFD, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAFC, 0xAAFF, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { "DoNothing", 0, 1, { 0xAAE3 } }, + { "HCS_Write12", 0, 33, { 0xAAF5, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00BC, 0xAAF3, 0xBB0C, 0xAAE7, 0x00BC, 0xAAF3, 0xBB04, 0xAAE7, 0xBB03, 0xAAF3, 0xBB00, 0xAAE7, 0x00BC, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAE8, 0x000A, 0xAAE9, 0xBB06, 0x000B, 0xAAF4 } }, + { "HCS_Verify12", 0, 11, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x000B, 0xAAF4, 0xAAF3, 0xBB03 } }, + { "HCS_Write18", 0, 33, { 0xAAF5, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00BC, 0xAAF3, 0xBB0C, 0xAAE7, 0x00BC, 0xAAF3, 0xBB04, 0xAAE7, 0xBB03, 0xAAF3, 0xBB00, 0xAAE7, 0x00BC, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAE8, 0x000A, 0xAAE9, 0xBB06, 0x0011, 0xAAF4 } }, + { "HCS_Verify18", 0, 11, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x0011, 0xAAF4, 0xAAF3, 0xBB03 } }, + { "HCS_Write360-361", 0, 34, { 0xAAEA, 0x0064, 0xAAD0, 0xBB07, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAF3, 0xBB06, 0xAAE8, 0x000A, 0xAAF3, 0xBB00, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAF3, 0xBB06, 0xAAE8, 0xBB10, 0xAAF3, 0xBB00, 0xAAE9, 0x000E, 0x000A, 0xAAF4 } }, + { "HCS_VPPSetup", 0, 25, { 0xAADB, 0xAADB, 0xAADB, 0xAAF5, 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00B2, 0xAAF3, 0xBB0C, 0xAAE8, 0xBB01 } }, + { "HCS_Verify360-361", 0, 14, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x000B, 0xAAF3, 0xBB03, 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF4 } }, + { "EE24_ProgEntry", 0, 7, { 0xAAF5, 0xAAF3, 0xBB06, 0xAACF, 0xBB01, 0xAAE8, 0xBB02 } }, + { "EE24_ProgExit", 0, 7, { 0xAAF4, 0xAAF3, 0xBB03, 0xAACF, 0xBB01, 0xAAE8, 0xBB02 } }, + { "EE24_RdPrep1Adr", 0, 4, { 0xAACD, 0xAACA, 0xAADB, 0xAACA } }, + { "EE24_Rd64", 0, 16, { 0xAACD, 0xAACA, 0xAADB, 0xAADB, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAE9, 0xBB04, 0x000E, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC8, 0xAACC } }, + { "EE24_Wr8Adr1.5ms", 0, 15, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_RdPrep2Adr", 0, 4, { 0xAACD, 0xAACA, 0xAACA, 0xAACA } }, + { "EE24_Wr32Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB03, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Wr1Adr1.5ms", 0, 8, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Rd16", 0, 16, { 0xAACD, 0xAACA, 0xAADB, 0xAADB, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAE9, 0xBB04, 0x0002, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC8, 0xAACC } }, + { "EE24_Wr16Adr1.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB01, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE25_ProgEntry", 0, 32, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB02, 0xAACF, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE8, 0x000A, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAFC, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB01, 0xAAC7, 0xBB00, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_ProgExit", 4, 10, { 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF3, 0xBB03, 0xAACF, 0xBB01, 0xAAE8, 0x000A, 0xAAF4 } }, + { "EE25_Rd64Adr1", 0, 18, { 0xAAFA, 0xAAF7, 0xAAC6, 0xAADB, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0xBB07, 0xAAF6, 0xAAFB } }, + { "EE25_Wr16Adr1.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB03, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr16Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB03, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Rd64Adr2", 0, 18, { 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0xBB07, 0xAAF6, 0xAAFB } }, + { "EE93_ProgEntry", 0, 10, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB02, 0xAACF, 0xBB00, 0xAAE8, 0x0014 } }, + { "EE93_Rd8Adr2.8", 0, 11, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAE9, 0xBB01, 0x0007, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWrPrep", 0, 8, { 0xAAF6, 0xAAFB, 0xAAC7, 0xBB26, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWr1A2.8", 0, 12, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB01, 0xAAE7, 0x001A } }, + { "EE93_ChpErase", 0, 20, { 0xAAF6, 0xAAFB, 0xAAC7, 0xBB26, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7, 0xAAE7, 0xBB05, 0xAAF6, 0xAAFB, 0xAAC7, 0xBB24, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB02 } }, + { "EE93_Rd1Adr2.16", 0, 9, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWr1A2.16", 0, 13, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB01, 0xAAE7, 0x0031 } }, + { "EE24_Wr64Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB07, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Wr128Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0x000F, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE25_Wr32Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB07, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr64Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x000F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr128Adr3.5ms", 0, 26, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB02, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x001F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Rd64Adr3", 0, 20, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB03, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0x0007, 0xAAF6, 0xAAFB } }, + { "MR_DbgVctWr2Int.3", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0x0002, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB01 } }, + { "MR_DbgVctWr2Ext.4", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "DBG_Halt.BL", 1, 8, { 0xAAF3, 0xBB06, 0xAAE7, 0x002F, 0xAAF3, 0xBB02, 0xAAE7, 0x0005 } }, + { "DBG_Run.BL", 0, 10, { 0xAAF5, 0xAAC1, 0xBB19, 0xAAC2, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAC2 } }, + { "DBG_RdDEVer.BL", 0, 11, { 0xAAF5, 0xAAC1, 0xBB02, 0xAAC2, 0xAAE6, 0xBB00, 0xBB05, 0xAAC2, 0xAAC2, 0xAAC2, 0xAAF4 } }, + { "DBG_SStep.BL", 0, 10, { 0xAAF5, 0xAAC1, 0xBB1A, 0xAAC2, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAC2 } }, + { "DBG_BulkWrData.BL", 0, 18, { 0xAAF5, 0xAAC1, 0xBB04, 0xAAC2, 0xAAE6, 0xBB00, 0x000C, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAC2, 0xAAF4 } }, + { "DBG_BulkRdData.BL", 0, 18, { 0xAAF5, 0xAAC1, 0xBB03, 0xAAC2, 0xAAE6, 0xBB00, 0x000C, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC2, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAC2, 0xAAF4 } }, + { "EE25_Wr128Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x001F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "HVProgEntryVppClose", 0, 22, { 0xAAFA, 0xAAF7, 0xAAFE, 0xAAFD, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x003C, 0xAAFC, 0xAAFF, 0xAAF6, 0xAAFB, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { 0, 0, 0, {} } +}; +} // namespace diff --git a/src/progs/pickit2v2/base/pickit2v2_data.h b/src/progs/pickit2v2/base/pickit2v2_data.h new file mode 100644 index 0000000..272fe92 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_data.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2V2_DATA_H +#define PICKIT2V2_DATA_H + +#include <qstring.h> + +namespace Pickit2V2 +{ + +enum ScriptType { + ProgEntry = 0x00, ProgExit = 0x01, DeviceIdRead = 0x02, ProgMemoryRead = 0x03, + EraseChipPrepare = 0x04, ProgMemoryAddressSet = 0x05, ProgMemoryWritePrepare = 0x06, + ProgMemoryWrite = 0x07, EepromReadPrepare = 0x08, EepromRead = 0x09, EepromWritePrepare = 0x0A, + EepromWrite = 0x0B, ConfigReadPrepare = 0x0C, ConfigRead = 0x0D, ConfigWritePrepare = 0x0E, + ConfigWrite = 0x0F, UserIdReadPrepare = 0x10, UserIdRead = 0x11, UserIdWritePrepare = 0x12, + UserIdWrite = 0x13, OsccalRead = 0x14, OsccalWrite = 0x15, ChipErase = 0x16, + ProgMemoryErase = 0x17, EepromErase = 0x18, ConfigErase = 0x19, + RowErase = 0x1A, TestMemoryRead = 0x1B, EEpromRowErase = 0x1C, + Nb_ScriptTypes = 0x1D +}; + +inline ScriptType prepareReadScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryAddressSet; + case Pic::MemoryRangeType::Eeprom: return EepromReadPrepare; + case Pic::MemoryRangeType::Config: return ConfigReadPrepare; + case Pic::MemoryRangeType::UserId: return UserIdReadPrepare; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType readScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryRead; + case Pic::MemoryRangeType::Eeprom: return EepromRead; + case Pic::MemoryRangeType::Config: return ConfigRead; + case Pic::MemoryRangeType::UserId: return UserIdRead; + case Pic::MemoryRangeType::Cal: return OsccalRead; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType prepareWriteScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryWritePrepare; + case Pic::MemoryRangeType::Eeprom: return EepromWritePrepare; + case Pic::MemoryRangeType::Config: return ConfigWritePrepare; + case Pic::MemoryRangeType::UserId: return UserIdWritePrepare; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType writeScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryWrite; + case Pic::MemoryRangeType::Eeprom: return EepromWrite; + case Pic::MemoryRangeType::Config: return ConfigWrite; + case Pic::MemoryRangeType::UserId: return UserIdWrite; + case Pic::MemoryRangeType::Cal: return OsccalWrite; + default: break; + } + return Nb_ScriptTypes; +} + +struct Data { + uchar codeMemoryNbReadWords, eepromMemoryNbReadWords; + uchar codeMemoryNbWriteWords, eepromMemoryNbWriteWords; + uchar scriptIndexes[Nb_ScriptTypes]; +}; +extern const Data &data(const QString &device); + +struct FamilyData { + Pic::Architecture architecture; + double vpp; + ushort progEntryScript, progExitScript, readDevIdScript; + bool progMemShift; +}; +extern const FamilyData FAMILY_DATA[]; + +struct ScriptData { + const char *name; + ushort version, length; + const ushort data[64]; +}; +extern const ScriptData SCRIPT_DATA[]; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/base/pickit2v2_prog.cpp b/src/progs/pickit2v2/base/pickit2v2_prog.cpp new file mode 100644 index 0000000..3a44bca --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_prog.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2v2_prog.h" + +#include "devices/list/device_list.h" +#include "progs/base/prog_config.h" +#include "pickit2v2.h" + +//---------------------------------------------------------------------------- +Pickit2V2::Base::Base(const Programmer::Group &group, const Pic::Data *data) + : Pickit2::Base(group, data) +{} + +VersionData Pickit2V2::Base::firmwareVersion(Programmer::FirmwareVersionType type) const +{ + switch (type.type()) { + case Programmer::FirmwareVersionType::Min: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Recommended: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Max: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Nb_Types: break; + } + Q_ASSERT(false); + return VersionData(); +} + +Pickit2V2::Hardware &Pickit2V2::Base::hardware() +{ + return static_cast<Hardware &>(*_hardware); +} + +bool Pickit2V2::Base::identifyDevice() +{ + double vdd = 3.3; // set 3.3V to check for fragile devices + if ( !_targetSelfPowered ) { + if ( !hardware().setVddVoltage(vdd, 0.85)) return false; + } + QString message = i18n("Unknown device"); + for (uint i=0; FAMILY_DATA[i].architecture!=Pic::Architecture::Nb_Types; i++) { + const FamilyData &fdata = FAMILY_DATA[i]; + if ( fdata.readDevIdScript==0 ) { + if ( device()->architecture()==fdata.architecture ) return true; // not autodetectable + continue; + } + hardware().setVddOn(false); + if ( fdata.vpp==0.0 ) hardware().setVppVoltage(vdd, 0.7); + else hardware().setVppVoltage(fdata.vpp, 0.7); + hardware().setVddOn(true); + if ( !hardware().executeScript(fdata.progEntryScript) ) return false; + if ( !hardware().executeScript(fdata.readDevIdScript) ) return false; + if ( !hardware().port().command(UploadData) ) return false; + Array data; + if ( !hardware().port().receive(data) ) return false; + if ( !hardware().executeScript(fdata.progExitScript) ) return false; + uint rawId = (data[2]<<8) + data[1]; + if (fdata.progMemShift) rawId >>= 1; + log(Log::DebugLevel::Normal, QString("Read id for family %1: %2").arg(fdata.architecture.key()).arg(toHexLabelAbs(rawId))); + QMap<QString, Device::IdData> ids; + ::Group::Base::ConstIterator it; + for (it=group().begin(); it!=group().end(); ++it) { + const Pic::Data *data = static_cast<const Pic::Data *>(it.data().data); + if ( data->architecture()!=fdata.architecture ) continue; + Device::IdData idata; + if ( data->matchId(rawId, idata) ) ids[it.key()] = idata; + } + if ( ids.count()!=0 ) { + log(Log::LineType::Information, i18n("Read id: %1").arg(device()->idNames(ids).join("; "))); + if ( ids.contains(device()->name()) ) return true; + message = i18n("Read id does not match the specified device name \"%1\".").arg(device()->name()); + break; + } + } + if ( !askContinue(message) ) { + logUserAbort(); + return false; + } + log(Log::LineType::Information, i18n("Continue with the specified device name: \"%1\"...").arg(device()->name())); + return true; +} + +bool Pickit2V2::Base::setTarget() +{ + if ( !identifyDevice() ) return false; + return hardware().setTarget(); +} + +bool Pickit2V2::Base::selfTest(bool ask) +{ + ushort status; + if ( !hardware().readStatus(status) ) return false; + QString error; + if ( status & VppError ) error += i18n("Vpp voltage level error; "); + if ( status & VddError ) error += i18n("Vdd voltage level error; "); + if ( error.isEmpty() ) return true; + log(Log::LineType::Warning, i18n("Self-test failed: %1").arg(error)); + if ( ask && !askContinue(i18n("Self-test failed (%1). Do you want to continue anyway?").arg(error)) ) { + logUserAbort(); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit2V2::Group::createHardware(Programmer::Base &base, const Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *Pickit2V2::Group::createDeviceSpecific(Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/pickit2v2/base/pickit2v2_prog.h b/src/progs/pickit2v2/base/pickit2v2_prog.h new file mode 100644 index 0000000..3653649 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_prog.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2V2_PROG_H +#define PICKIT2V2_PROG_H + +#include "progs/pickit2/base/pickit2_prog.h" + +namespace Pickit2V2 +{ +class Hardware; + +//---------------------------------------------------------------------------- +class Base : public Pickit2::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data); + virtual bool setTarget(); + +private: + Hardware &hardware(); + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual bool verifyDeviceId() { return true; } // it is done by "setTarget" + virtual bool selfTest(bool ask); + bool identifyDevice(); +}; + +//---------------------------------------------------------------------------- +class Group : public Programmer::PicGroup +{ +public: + virtual QString name() const { return "pickit2v2"; } + virtual QString label() const { return i18n("PICkit2 Firmware 2.x"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetPowerModeFromConfig; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::USB ); } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit2V2::Base(*this, static_cast<const Pic::Data *>(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/gui/Makefile.am b/src/progs/pickit2v2/gui/Makefile.am new file mode 100644 index 0000000..dae6832 --- /dev/null +++ b/src/progs/pickit2v2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2v2ui.la +libpickit2v2ui_la_SOURCES = pickit2v2_group_ui.cpp +libpickit2v2ui_la_LDFLAGS = $(all_libraries)
\ No newline at end of file diff --git a/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp b/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp new file mode 100644 index 0000000..b3596fd --- /dev/null +++ b/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "pickit2v2_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" + +::Programmer::ConfigWidget *Pickit2V2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit2V2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new ::Programmer::AdvancedDialog(static_cast<Base &>(base), parent, "pickit2v2_advanced_dialog"); +} diff --git a/src/progs/pickit2v2/gui/pickit2v2_group_ui.h b/src/progs/pickit2v2/gui/pickit2v2_group_ui.h new file mode 100644 index 0000000..6c5ff64 --- /dev/null +++ b/src/progs/pickit2v2/gui/pickit2v2_group_ui.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 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 PICKIT2V2_GROUP_UI_H +#define PICKIT2V2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Pickit2V2 +{ +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/pickit2v2/pickit2v2.pro b/src/progs/pickit2v2/pickit2v2.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/pickit2v2/pickit2v2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/progs.pro b/src/progs/progs.pro new file mode 100644 index 0000000..3b9a442 --- /dev/null +++ b/src/progs/progs.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = base list direct icd2 icd1 pickit2 pickit1 psp gpsim pickit2v2 \ + bootloader tbl_bootloader pickit2_bootloader picdem_bootloader manager diff --git a/src/progs/psp/Makefile.am b/src/progs/psp/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/psp/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/psp/base/Makefile.am b/src/progs/psp/base/Makefile.am new file mode 100644 index 0000000..93ce348 --- /dev/null +++ b/src/progs/psp/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpsp.la +libpsp_la_SOURCES = psp_prog.cpp psp_serial.cpp psp_data.cpp psp.cpp +libpsp_la_DEPENDENCIES = psp_data.cpp + +noinst_DATA = psp.xml +psp_data.cpp: ../xml/xml_psp_parser psp.xml + ../xml/xml_psp_parser +CLEANFILES = psp_data.cpp diff --git a/src/progs/psp/base/base.pro b/src/progs/psp/base/base.pro new file mode 100644 index 0000000..4dca18d --- /dev/null +++ b/src/progs/psp/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = psp +HEADERS += psp.h psp_prog.h psp_data.h psp_serial.h +SOURCES += psp.cpp psp_prog.cpp psp_data.cpp psp_serial.cpp diff --git a/src/progs/psp/base/psp.cpp b/src/progs/psp/base/psp.cpp new file mode 100644 index 0000000..1b76bf5 --- /dev/null +++ b/src/progs/psp/base/psp.cpp @@ -0,0 +1,346 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "psp.h" + +#include "common/global/global.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +QMemArray<uchar> Psp::createConfigInfo(const Pic::Data &data) +{ + QMemArray<uchar> array(33); + array.fill(0x00); + + const Pic::Config &config = data.config(); + for (uint i=0; i<uint(config._words.count()); i++) { + BitValue v = config._words[i].usedMask(); + if ( data.nbBytesWord(Pic::MemoryRangeType::UserId)==1 ) array[i ^ 1] = v.byte(0); + else { + array[2*i] = v.byte(1); + array[2*i + 1] = v.byte(0); + } + } + for (uint i=0; i<16; i++) array[i + 16] = array[i]; + + // checksum + for (uint i=0; i<32; i++) array[32] += array[i]; + + return array; +} + +QMemArray<uchar> Psp::createDeviceInfo(const Pic::Data &data) +{ + QMemArray<uchar> config = createConfigInfo(data); + QMemArray<uchar> array(45); + array.fill(0x00); + + // memory code length + BitValue v = data.nbWords(Pic::MemoryRangeType::Code); + array[0] = v.byte(1); + array[1] = v.byte(0); + // address word width + v = data.mask(Pic::MemoryRangeType::Code); + array[2] = v.byte(1); + array[3] = v.byte(0); + // data word width + array[4] = v.byte(1); + array[5] = v.byte(0); + + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) { + // user id width + v = data.userIdRecommendedMask(); + if ( data.nbBytesWord(Pic::MemoryRangeType::UserId)==1 ) v += v << 8; + array[6] = v.byte(1); + array[7] = v.byte(0); + // user id mask + array[8] = v.byte(1); + array[9] = v.byte(0); + } + + // memory config mask + array[10] = config[0]; + array[11] = config[1]; + array[12] = config[16]; + array[13] = config[17]; + + if ( data.isReadable(Pic::MemoryRangeType::Eeprom) ) { + // memory eeprom width + v = data.mask(Pic::MemoryRangeType::Eeprom); + array[14] = v.byte(1); + array[15] = v.byte(0); + // memory eeprom mask + array[16] = v.byte(1); + array[17] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) { + // memory calibration width + v = data.mask(Pic::MemoryRangeType::Cal); + array[18] = v.byte(1); + array[19] = v.byte(0); + // memory calibration mask + array[20] = v.byte(1); + array[21] = v.byte(0); + } + + // memory code start + array[22] = 0x00; + array[23] = 0x00; + // memory code length + array[24] = 0x00; // array[0]; in lplab and for some devices in picp... + array[25] = 0x01; // array[1]; in lplab and for some devices in picp... + + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) { + // user id start + v = data.range(Pic::MemoryRangeType::UserId).start.toUInt(); + array[26] = v.byte(1); + array[27] = v.byte(0); + // user id length + v = data.nbWords(Pic::MemoryRangeType::UserId); + if ( data.nbBytesWord(Pic::MemoryRangeType::UserId)==1 ) v >>= 1; + array[28] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Config) ) { + // config start + v = data.range(Pic::MemoryRangeType::Config).start.toUInt(); + array[29] = v.byte(1); + array[30] = v.byte(0); + // config length + v = data.nbWords(Pic::MemoryRangeType::Config); + if ( data.nbBytesWord(Pic::MemoryRangeType::Config)==1 ) v >>= 1; + array[31] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Config) ) { + // eeprom start + array[32] = 0x00; + array[33] = 0x00; + // eeprom length + v = data.nbWords(Pic::MemoryRangeType::Eeprom); + array[34] = v.byte(1); + array[35] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) { + // calibration start + v = data.range(Pic::MemoryRangeType::Cal).start.toUInt(); + array[36] = v.byte(1); + array[37] = v.byte(0); + // calibration length + v = data.nbWords(Pic::MemoryRangeType::Cal); + array[38] = v.byte(1); + array[39] = v.byte(0); + } + + // programming + const Psp::Data &pdata = Psp::data(data.name()); + array[40] = pdata.overprogram; + array[41] = pdata.tries; + array[42] = pdata.algorithm; + if ( data.memoryTechnology()==Device::MemoryTechnology::Flash ) array[43] |= 0x01; + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) array[43] |= 0x02; + if ( data.isReadable(Pic::MemoryRangeType::Config) ) array[43] |= 0x04; + if ( data.isReadable(Pic::MemoryRangeType::Eeprom) ) array[43] |= 0x08; + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) array[43] |= 0x10; + if ( data.config().findMask("PARITY") ) array[43] |= 0x20; + + // checksum + for (uint i=0; i<44; i++) array[44] += array[i]; + + return array; +} + +//----------------------------------------------------------------------------- +Psp::Hardware::Hardware(::Programmer::Base &base, const QString &portDevice) + : Programmer::PicHardware(base, new SerialPort(portDevice, base), QString::null) +{} + +bool Psp::Hardware::internalConnectHardware() +{ + if ( !port()->open() ) return false; + if ( !port()->reset() ) return false; + // #### TODO: detect Warp13 or JuPic + QMemArray<uchar> a; + if ( !port()->command(0x88, 1, a) ) return false; + if ( a[0]!=0xAB ) { + log(Log::LineType::Error, i18n("Wrong programmer connected")); + return false; + } + return true; +} + +bool Psp::Hardware::getFirmwareVersion(VersionData &version) +{ + QMemArray<uchar> a1; + if ( !port()->commandAck(0x8D, 2, &a1) ) return false; + if ( a1[1]==0xFF ) { + log(Log::LineType::Warning, i18n("Invalid firmware version")); + version = VersionData(0xFF, 0, 0); + } else { + QMemArray<uchar> a2; + if ( !port()->receive(2, a2) ) return false; + version = VersionData(a1[1], a2[0], a2[1]); + } + return true; +} + +bool Psp::Hardware::setTarget() +{ + log(Log::DebugLevel::Max, "set target"); + // load device info + if ( !port()->commandAck(0x81) ) return false; + QMemArray<uchar> a = createDeviceInfo(device()); + if ( !port()->send(a) ) return false; + if ( !port()->receiveEnd() ) return false; + + // load config info + if ( !port()->commandAck(0x82) ) return false; + a = createConfigInfo(device()); + if ( !port()->send(a) ) return false; + if ( !port()->receiveEnd() ) return false; + + return true; +} + +bool Psp::Hardware::setRange(uint start, uint size) +{ + QMemArray<uchar> a(6); + a[0] = 0x8E; + a[1] = start >> 16; + a[2] = (start >> 8) & 0xFF; + a[3] = start & 0xFF; + a[4] = size >> 8; + a[5] = size & 0xFF; + if ( !port()->send(a) ) return false; + QMemArray<uchar> r; + if ( !port()->receive(6, r) ) return false; + for (uint i=0; i<6; i++) { + if ( r[i]!=a[i] ) { + log(Log::LineType::Error, i18n("Failed to set range")); + return false; + } + } + return true; +} + +char Psp::Hardware::readCommand(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 'T'; + case Pic::MemoryRangeType::Eeprom: return 'd'; + case Pic::MemoryRangeType::Config: return 'f'; + case Pic::MemoryRangeType::UserId: return 'e'; + case Pic::MemoryRangeType::Cal: return 'c'; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + return 0; +} + +char Psp::Hardware::writeCommand(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 'Q'; + case Pic::MemoryRangeType::Eeprom: return 'i'; + case Pic::MemoryRangeType::Config: return 'g'; + case Pic::MemoryRangeType::UserId: return 'h'; + case Pic::MemoryRangeType::Cal: return 'q'; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + return 0; +} + +bool Psp::Hardware::readMemory(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + QMemArray<uchar> a; + uint nbWords = device().nbWords(type); + data.resize(nbWords); + uint nbBytes = nbWords * device().nbBytesWord(type); + char c = readCommand(type); + switch (type.type()) { + case Pic::MemoryRangeType::Code: + if ( !setRange(0, nbWords) ) return false; + if ( !port()->commandAck(c) ) return false; + for (uint i=0; i<data.count(); i++) { + if ( !port()->receive(2, a) ) return false; + data[i] = (a[0] << 8) + a[1]; +// log(Log::DebugLevel::Max, QString("code data %1: %2 (%3, %4)").arg(i).arg(toHexLabel(data[i], 4)) +// .arg(toHexLabel(a[0], 2)).arg(toHexLabel(a[1], 2))); + } + if ( !port()->receiveEnd() ) return false; + break; + case Pic::MemoryRangeType::Eeprom: + if ( !port()->commandAck(c) ) return false; + for (uint i=0; i<data.count(); i++) { + if ( !port()->receive(1, a) ) return false; + data[i] = a[0]; + } + if ( !port()->receiveEnd() ) return false; + break; + case Pic::MemoryRangeType::UserId: + if ( !port()->commandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; i<data.count(); i++) data[i] = (a[1+2*i] << 8) + a[1+2*i+1]; + break; + case Pic::MemoryRangeType::Config: + if ( !port()->commandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; i<data.count(); i++) data[i] = (a[1+2*i] << 8) + a[1+2*i+1]; + break; + case Pic::MemoryRangeType::Cal: + if ( !setRange(0, nbWords) ) return false; + if ( !port()->commandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; i<data.count(); i++) data[i] = (a[1+2*i] << 8) + a[1+2*i+1]; + break; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::CalBackup: + data.resize(0); + return true; + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + if (vdata) { + for (uint i=0; i<data.count(); i++) + if ( !verifyWord(i, data[i], type, *vdata) ) return false; + } + return true; +} + +bool Psp::Hardware::writeMemory(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_UNUSED(force); // #### TODO: optimize for program memory + if ( type==Pic::MemoryRangeType::Code && !setRange(0, data.count()) ) return false; + uint nbBytes = device().nbBytesWord(type); + if ( !port()->commandAck(writeCommand(type)) ) return false; + for (uint i=0; i<data.count(); i++) + if ( !port()->sendData(data[i].toUInt(), nbBytes) ) return false; + return port()->receiveEnd(); +} + +bool Psp::Hardware::eraseAll() +{ + QMemArray<uchar> a; + if ( !port()->commandAck(0x8F, 2, &a) ) return false; + if ( a[1]!=0x00 ) { + log(Log::LineType::Error, i18n("Erase failed")); + return false; + } + return true; +} diff --git a/src/progs/psp/base/psp.h b/src/progs/psp/base/psp.h new file mode 100644 index 0000000..ad4a160 --- /dev/null +++ b/src/progs/psp/base/psp.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 PSP_H +#define PSP_H + +#include "devices/pic/prog/pic_prog.h" +#include "psp_serial.h" +#include "psp_data.h" + +namespace Psp +{ + extern QMemArray<uchar> createConfigInfo(const Pic::Data &data); + extern QMemArray<uchar> createDeviceInfo(const Pic::Data &data); + +//----------------------------------------------------------------------------- +class Hardware : public Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + SerialPort *port() { return static_cast<SerialPort *>(_port); } + virtual bool uploadFirmware(const Pic::Memory &) { return false; } + virtual bool setTarget(); + virtual bool getFirmwareVersion(VersionData &version); + virtual bool readMemory(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool eraseAll(); + virtual bool internalConnectHardware(); + +private: + bool setRange(uint start, uint end); + static char readCommand(Pic::MemoryRangeType type); + static char writeCommand(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual bool canReadRange(Pic::MemoryRangeType type) const { return ( type!=Pic::MemoryRangeType::DeviceId ); } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return hardware().eraseAll(); } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) { return hardware().readMemory(type, data, vdata); } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) { return hardware().writeMemory(type, data, force); } +}; + +} // namespace + +#endif diff --git a/src/progs/psp/base/psp.xml b/src/progs/psp/base/psp.xml new file mode 100644 index 0000000..a009584 --- /dev/null +++ b/src/progs/psp/base/psp.xml @@ -0,0 +1,195 @@ +<!-- ************************************************************************* --> +<!-- * Copyright (C) 2005-2007 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="psp"> + <device name="10F200" family="generic" algorithm="29" overprogram="1" tries="1" /> + <device name="10F202" family="generic" algorithm="29" overprogram="1" tries="1" /> + <device name="10F204" family="generic" algorithm="29" overprogram="1" tries="1" /> + <device name="10F206" family="generic" algorithm="29" overprogram="1" tries="1" /> + + <device name="12C508" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12C508A" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12F508" family="generic" algorithm="28" overprogram="1" tries="1" /> + <device name="12C509" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12C509A" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12F509" family="generic" algorithm="28" overprogram="1" tries="1" /> + <device name="12C671" family="generic" algorithm="9" overprogram="3" tries="25" /> + <device name="12C672" family="generic" algorithm="9" overprogram="3" tries="25" /> + <device name="12CE518" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12CE519" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12CE673" family="generic" algorithm="9" overprogram="3" tries="25" /> + <device name="12CE674" family="generic" algorithm="9" overprogram="3" tries="25" /> + <device name="12CR509A" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="12F629" family="generic" algorithm="15" overprogram="1" tries="1" support_type="tested" /> + <device name="12F675" family="generic" algorithm="15" overprogram="1" tries="1" support_type="tested" /> + <device name="12F683" family="generic" algorithm="15" overprogram="1" tries="1" support_type="tested" /> + + <device name="14000" family="generic" algorithm="1" overprogram="3" tries="25" /> + + <device name="16C505" family="generic" algorithm="10" overprogram="11" tries="8" /> + <device name="16C52" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C54" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C54A" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C54B" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C54C" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C55" family="generic" algorithm="6" overprogram="11" tries="8" /> + <device name="16C554" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C558" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C55A" family="generic" algorithm="6" overprogram="11" tries="8" /> + <device name="16C56" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C56A" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C57" family="generic" algorithm="6" overprogram="11" tries="8" /> + <device name="16C57C" family="generic" algorithm="6" overprogram="11" tries="8" /> + <device name="16C58A" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C58B" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16C61" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C62" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C620" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C620A" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C621" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C621A" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C622" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C622A" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C62A" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C62B" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C63" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C63A" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C64" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C642" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C64A" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C65" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C65A" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C65B" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C66" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C662" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C67" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C71" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C710" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C711" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C712" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C715" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C716" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16C717" family="generic" algorithm="12" overprogram="3" tries="25" /> + <device name="16C72" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C72A" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C73" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C73A" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C73B" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C74" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C745" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C74A" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C74B" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C76" family="generic" algorithm="3" overprogram="3" tries="25" /> + <device name="16C765" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C77" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C770" family="generic" algorithm="8" overprogram="3" tries="25" /> + <device name="16C771" family="generic" algorithm="8" overprogram="3" tries="25" /> + <device name="16C773" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C774" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C781" family="generic" algorithm="8" overprogram="3" tries="25" /> + <device name="16C782" family="generic" algorithm="8" overprogram="3" tries="25" /> + <device name="16C84" family="generic" algorithm="2" overprogram="3" tries="1" /> + <device name="16C923" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C924" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C925" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16C926" family="generic" algorithm="4" overprogram="3" tries="25" /> + <device name="16CE623" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16CE624" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16CE625" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16CR620A" family="generic" algorithm="2" overprogram="3" tries="25" /> + <device name="16CR72" family="generic" algorithm="3" overprogram="3" tries="25" /> + + <device name="16F54" family="generic" algorithm="5" overprogram="11" tries="8" /> + <device name="16F57" family="generic" algorithm="6" overprogram="11" tries="8" /> + <device name="16F627" family="generic" algorithm="12" overprogram="0" tries="1" support_type="tested" /> + <device name="16F627A" family="generic" algorithm="19" overprogram="0" tries="1" /> + <device name="16F628" family="generic" algorithm="12" overprogram="0" tries="1" support_type="tested" /> + <device name="16F628A" family="generic" algorithm="19" overprogram="0" tries="1" /> + <device name="16F630" family="generic" algorithm="15" overprogram="0" tries="1" /> + <device name="16F648A" family="generic" algorithm="19" overprogram="1" tries="1" /> + <device name="16F676" family="generic" algorithm="15" overprogram="0" tries="1" /> + <device name="16F684" family="generic" algorithm="21" overprogram="0" tries="1" /> + <device name="16F688" family="generic" algorithm="21" overprogram="0" tries="1" /> + <device name="16F690" family="generic" algorithm="21" overprogram="0" tries="1" /> + <device name="16F716" family="generic" algorithm="22" overprogram="0" tries="1" /> + <device name="16F72" family="generic" algorithm="13" overprogram="0" tries="1" /> + <device name="16F73" family="generic" algorithm="13" overprogram="0" tries="1" /> + <device name="16F737" family="generic" algorithm="23" overprogram="3" tries="1" /> + <device name="16F74" family="generic" algorithm="13" overprogram="0" tries="1" /> + <device name="16F747" family="generic" algorithm="23" overprogram="3" tries="1" /> + <device name="16F76" family="generic" algorithm="13" overprogram="0" tries="1" /> + <device name="16F767" family="generic" algorithm="23" overprogram="3" tries="1" /> + <device name="16F77" family="generic" algorithm="13" overprogram="0" tries="1" /> + <device name="16F777" family="generic" algorithm="23" overprogram="3" tries="1" /> + <device name="16F818" family="generic" algorithm="16" overprogram="0" tries="1" /> + <device name="16F819" family="generic" algorithm="16" overprogram="0" tries="1" /> + <device name="16F83" family="generic" algorithm="2" overprogram="3" tries="1" /> + <device name="16F84" family="generic" algorithm="2" overprogram="3" tries="1" /> + <device name="16F84A" family="generic" algorithm="2" overprogram="0" tries="1" /> + <device name="16F87" family="generic" algorithm="20" overprogram="0" tries="1" /> + <device name="16F870" family="generic" algorithm="3" overprogram="0" tries="1" /> + <device name="16F871" family="generic" algorithm="4" overprogram="0" tries="1" /> + <device name="16F872" family="generic" algorithm="3" overprogram="0" tries="1" /> + <device name="16F873" family="generic" algorithm="4" overprogram="0" tries="1" support_type="tested" /> + <device name="16F873A" family="generic" algorithm="17" overprogram="0" tries="1" /> + <device name="16F874" family="generic" algorithm="4" overprogram="0" tries="1" /> + <device name="16F874A" family="generic" algorithm="17" overprogram="0" tries="1" /> + <device name="16F876" family="generic" algorithm="4" overprogram="0" tries="1" /> + <device name="16F876A" family="generic" algorithm="17" overprogram="0" tries="1" /> + <device name="16F877" family="generic" algorithm="4" overprogram="0" tries="1" /> + <device name="16F877A" family="generic" algorithm="17" overprogram="0" tries="1" /> + <device name="16F88" family="generic" algorithm="20" overprogram="0" tries="1" /> + <device name="16F913" family="generic" algorithm="32" overprogram="1" tries="3" /> + <device name="16F917" family="generic" algorithm="32" overprogram="1" tries="3" /> + <device name="16HV540" family="generic" algorithm="5" overprogram="11" tries="8" /> + + <device name="17C42" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C42A" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C43" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C44" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C752" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C756" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C756A" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C762" family="generic" algorithm="7" overprogram="3" tries="25" /> + <device name="17C766" family="generic" algorithm="7" overprogram="3" tries="25" /> +<!-- + <device name="18C242" family="generic" algorithm="11" overprogram="3" tries="25" /> + <device name="18C252" family="generic" algorithm="11" overprogram="3" tries="25" /> + <device name="18C442" family="generic" algorithm="11" overprogram="3" tries="25" /> + <device name="18C452" family="generic" algorithm="11" overprogram="3" tries="25" /> + <device name="18C658" family="generic" algorithm="11" overprogram="3" tries="25" /> + <device name="18C858" family="generic" algorithm="11" overprogram="3" tries="25" /> + + <device name="18F1220" family="generic" algorithm="18" overprogram="1" tries="1" /> + <device name="18F1320" family="generic" algorithm="18" overprogram="1" tries="1" /> + <device name="18F2220" family="generic" algorithm="24" overprogram="1" tries="1" /> + <device name="18F2320" family="generic" algorithm="24" overprogram="1" tries="1" /> + <device name="18F242" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F2455" family="generic" algorithm="30" overprogram="3" tries="13" /> + <device name="18F248" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F252" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F258" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F2680" family="generic" algorithm="30" overprogram="3" tries="13" /> + <device name="18F4220" family="generic" algorithm="24" overprogram="1" tries="1" /> + <device name="18F4320" family="generic" algorithm="24" overprogram="1" tries="1" /> + <device name="18F442" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F4431" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F4455" family="generic" algorithm="30" overprogram="3" tries="13" /> + <device name="18F448" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F452" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F4550" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F458" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F6620" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F6520" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F6720" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F8620" family="generic" algorithm="14" overprogram="3" tries="25" /> + <device name="18F8720" family="generic" algorithm="14" overprogram="3" tries="25" /> +--> +</type> diff --git a/src/progs/psp/base/psp_data.h b/src/progs/psp/base/psp_data.h new file mode 100644 index 0000000..c643961 --- /dev/null +++ b/src/progs/psp/base/psp_data.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * 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 PSP_DATA_H +#define PSP_DATA_H + +#include <qstring.h> + +namespace Psp +{ + struct Data { + uint algorithm, overprogram, tries; + }; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/psp/base/psp_prog.cpp b/src/progs/psp/base/psp_prog.cpp new file mode 100644 index 0000000..891cb73 --- /dev/null +++ b/src/progs/psp/base/psp_prog.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * 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 "psp_prog.h" + +//---------------------------------------------------------------------------- +bool Psp::Base::readFirmwareVersion() +{ + return hardware().getFirmwareVersion(_firmwareVersion); +} + +//---------------------------------------------------------------------------- +Programmer::Properties Psp::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; // | ::Programmer::CanUploadFirmware; +} + +Programmer::Hardware *Psp::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + return new Hardware(base, hd.port.device); +} + +Programmer::DeviceSpecific *Psp::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/psp/base/psp_prog.h b/src/progs/psp/base/psp_prog.h new file mode 100644 index 0000000..ef525cd --- /dev/null +++ b/src/progs/psp/base/psp_prog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * 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 PSP_PROG_H +#define PSP_PROG_H + +#include "common/global/global.h" +#include "psp.h" + +namespace Psp +{ +//----------------------------------------------------------------------------- +class Base : public Programmer::PicBase +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "psp_programmer_base") {} + virtual bool readFirmwareVersion(); + virtual bool setTarget() { return hardware().setTarget(); } + +protected: + Hardware &hardware() { return static_cast<Hardware &>(*_hardware); } + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const { return (type==Programmer::FirmwareVersionType::Min ? VersionData(4, 30, 3) : VersionData()); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "psp"; } + virtual QString label() const { return i18n("Picstart Plus"); } + virtual QString xmlName() const { return "psp"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial ); } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ::Psp::Base(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/psp/base/psp_serial.cpp b/src/progs/psp/base/psp_serial.cpp new file mode 100644 index 0000000..964d604 --- /dev/null +++ b/src/progs/psp/base/psp_serial.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 "psp_serial.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +Psp::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedFlush, log) +{} + +bool Psp::SerialPort::open() +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | IgnoreControlLines | EnableReceiver, S19200, 100); +} + +bool Psp::SerialPort::reset() +{ + if ( !setHardwareFlowControl(false) ) return false; + // reset + setPinOn(DTR, false, Port::PositiveLogic); + Port::msleep(250); + // remove reset + setPinOn(DTR, true, Port::PositiveLogic); + for (uint i=0; i<=100; i++) { + bool bit; + if ( !readPin(CTS, Port::PositiveLogic, bit) ) return false; + if ( bit ) break; + if ( i==100 ) { + log(Log::LineType::Error, i18n("Could not contact Picstart+")); + return false; + } + Port::msleep(1); + } + if ( !setHardwareFlowControl(true) ) return false; + return flush(0); +} + +bool Psp::SerialPort::command(uchar c, uint nbBytes, QMemArray<uchar> &a) +{ + log(Log::DebugLevel::Extra, QString("Command %1").arg(toHexLabel(c, 2))); + if ( !sendChar(c) ) return false; + return receive(nbBytes, a); +} + +bool Psp::SerialPort::checkAck(uchar ec, uchar rc) +{ + if ( ec==rc ) return true; + log(Log::LineType::Error, i18n("Incorrect ack: expecting %1, received %2") + .arg(QString(toHex(ec, 2))).arg(QString(toHex(rc, 2)))); + return false; +} + +bool Psp::SerialPort::checkEnd(uchar c) +{ + if ( c==0 ) return true; + log(Log::LineType::Error, i18n("Incorrect received data end: expecting 00, received %1") + .arg(QString(toHex(c, 2)))); + return false; +} + +bool Psp::SerialPort::commandAck(uchar c, uint nbBytes, QMemArray<uchar> *a) +{ + Q_ASSERT( nbBytes>=1 ); + QMemArray<uchar> tmp; + if ( !command(c, nbBytes, tmp) ) return false; + if ( !checkAck(c, tmp[0]) ) return false; + if (a) *a = tmp; + return true; +} + +bool Psp::SerialPort::receiveEnd() +{ + QMemArray<uchar> a; + if ( !receive(1, a) ) return false; + if ( !checkEnd(a[0]) ) return false; + return true; +} + +bool Psp::SerialPort::commandAckEnd(uchar c, uint nbBytes, QMemArray<uchar> &a) +{ + Q_ASSERT( nbBytes>=2 ); + if ( !command(c, nbBytes, a) ) return false; + if ( !checkAck(c, a[0]) ) return false; + if ( !checkEnd(a[nbBytes-1]) ) return false; + return true; +} + +bool Psp::SerialPort::sendData(uint value, uint nbBytes) +{ + Q_ASSERT( nbBytes==1 || nbBytes==2 ); + Q_ASSERT( value<uint(1 << 8*nbBytes) ); + QMemArray<uchar> a(nbBytes); + if ( nbBytes==2 ) { + a[0] = value / 256; + a[1] = value & 0xFF; + } else a[0] = value; + if ( !send(a) ) return false; + return receive(nbBytes, a); +} diff --git a/src/progs/psp/base/psp_serial.h b/src/progs/psp/base/psp_serial.h new file mode 100644 index 0000000..6f379dd --- /dev/null +++ b/src/progs/psp/base/psp_serial.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> * + * * + * 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 PSP_SERIAL_H +#define PSP_SERIAL_H + +#include "common/port/serial.h" + +namespace Psp +{ + +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(); + bool reset(); + bool command(uchar c, uint nbBytes, QMemArray<uchar> &a); + bool commandAck(uchar c, uint nbBytes = 1, QMemArray<uchar> *a = 0); + bool commandAckEnd(uchar c, uint nbBytes, QMemArray<uchar> &a); + bool receiveEnd(); + bool sendData(uint value, uint nbBytes); + +private: + bool checkAck(uchar ec, uchar rc); + bool checkEnd(uchar c); +}; + +} // namespace + +#endif diff --git a/src/progs/psp/gui/Makefile.am b/src/progs/psp/gui/Makefile.am new file mode 100644 index 0000000..c11240d --- /dev/null +++ b/src/progs/psp/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpspui.la +libpspui_la_LDFLAGS = $(all_libraries) +libpspui_la_SOURCES = psp_group_ui.cpp diff --git a/src/progs/psp/gui/psp_group_ui.cpp b/src/progs/psp/gui/psp_group_ui.cpp new file mode 100644 index 0000000..e3f2546 --- /dev/null +++ b/src/progs/psp/gui/psp_group_ui.cpp @@ -0,0 +1,22 @@ +/*************************************************************************** + * 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 "psp_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "devices/pic/gui/pic_prog_group_ui.h" + +::Programmer::ConfigWidget *Psp::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} + +::Programmer::AdvancedDialog *Psp::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new ::Programmer::PicAdvancedDialog(static_cast< ::Programmer::PicBase &>(base), parent, "psp_advanced_dialog"); +} diff --git a/src/progs/psp/gui/psp_group_ui.h b/src/progs/psp/gui/psp_group_ui.h new file mode 100644 index 0000000..fc1534a --- /dev/null +++ b/src/progs/psp/gui/psp_group_ui.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * 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 PSP_GROUP_UI_H +#define PSP_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Psp +{ +class Group; + +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/psp/psp.pro b/src/progs/psp/psp.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/psp/psp.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/psp/xml/Makefile.am b/src/progs/psp/xml/Makefile.am new file mode 100644 index 0000000..156e485 --- /dev/null +++ b/src/progs/psp/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_psp_parser +xml_psp_parser_SOURCES = xml_psp_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_psp_parser_DEPENDENCIES = $(OBJECTS) +xml_psp_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/psp/xml/xml.pro b/src/progs/psp/xml/xml.pro new file mode 100644 index 0000000..0c88b4c --- /dev/null +++ b/src/progs/psp/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_psp_parser +SOURCES += xml_psp_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_psp_parser +unix:QMAKE_CLEAN += ../base/psp_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_psp_parser.exe +win32:QMAKE_CLEAN += ..\base\psp_data.cpp diff --git a/src/progs/psp/xml/xml_psp_parser.cpp b/src/progs/psp/xml/xml_psp_parser.cpp new file mode 100644 index 0000000..5cdd289 --- /dev/null +++ b/src/progs/psp/xml/xml_psp_parser.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * 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 "xml_to_data/prog_xml_to_data.h" +#include "progs/psp/base/psp_data.h" + +//----------------------------------------------------------------------------- +namespace Psp +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("psp", "Psp") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void Psp::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.algorithm = element.attribute("algorithm").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid algorithm"); + data.overprogram = element.attribute("overprogram").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid overprogram"); + data.tries = element.attribute("tries").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid tries"); +} + +void Psp::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << data.algorithm << ", " << data.overprogram << ", " << data.tries; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Psp::XmlToData) diff --git a/src/progs/sdcdb/Makefile b/src/progs/sdcdb/Makefile new file mode 100644 index 0000000..e57c92d --- /dev/null +++ b/src/progs/sdcdb/Makefile @@ -0,0 +1,733 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 877 $ +# src/progs/sdcdb/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +srcdir = . +top_srcdir = ../../.. + +pkgdatadir = $(datadir)/piklab +pkglibdir = $(libdir)/piklab +pkgincludedir = $(includedir)/piklab +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c -p +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i486-pc-linux-gnu +host_triplet = i486-pc-linux-gnu +target_triplet = i486-pc-linux-gnu +subdir = src/progs/sdcdb +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ +#>- html-recursive info-recursive install-data-recursive \ +#>- install-exec-recursive install-info-recursive \ +#>- install-recursive installcheck-recursive installdirs-recursive \ +#>- pdf-recursive ps-recursive uninstall-info-recursive \ +#>- uninstall-recursive +#>+ 6 +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive nmcheck-recursive bcheck-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run tar +AR = ar +ARTSCCONFIG = /usr/bin/artsc-config +AUTOCONF = $(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure +AUTODIRS = +AUTOHEADER = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run autoheader +AUTOMAKE = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run automake-1.9 +AWK = mawk +BSD_FALSE = +BSD_TRUE = # +CC = i486-linux-gnu-gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -O2 -Wall -g -O2 -Wformat-security -Wmissing-format-attribute +CONF_FILES = $(top_srcdir)/./admin/configure.in.min $(top_srcdir)/configure.in.in $(top_srcdir)/configure.in.mid +CPP = i486-linux-gnu-gcc -E +CPPFLAGS = -DQT_THREAD_SUPPORT -D_REENTRANT -L/usr/lib +CXX = i486-linux-gnu-g++ +CXXCPP = i486-linux-gnu-g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -Wno-long-long -Wundef -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -O2 -Wformat-security -Wmissing-format-attribute -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION +CYGPATH_W = echo +DCOPIDL = /usr/bin/dcopidl +DCOPIDL2CPP = /usr/bin/dcopidl2cpp +DCOPIDLNG = +DCOP_DEPENDENCIES = $(DCOPIDL) +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +ENABLE_PERMISSIVE_FLAG = -fpermissive +EXEEXT = +F77 = +FFLAGS = +FRAMEWORK_COREAUDIO = +GMSGFMT = /usr/bin/msgfmt +GREP = /bin/grep +HAVE_GCC_VISIBILITY = 0 +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} $(INSTALL_STRIP_FLAG) +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +KCFG_DEPENDENCIES = +KCONFIG_COMPILER = +KDECONFIG = /usr/bin/kde-config +KDE_CHECK_PLUGIN = $(KDE_PLUGIN) -rpath $(libdir) +KDE_EXTRA_RPATH = +KDE_INCLUDES = -I/usr/include/kde +KDE_LDFLAGS = -L/usr/lib +KDE_MT_LDFLAGS = +KDE_MT_LIBS = -lpthread +KDE_NO_UNDEFINED = -Wl,--no-undefined -Wl,--allow-shlib-undefined +KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS) +KDE_RPATH = -R $(libdir) -R $(kde_libraries) -R $(qt_libraries) -R $(x_libraries) +KDE_USE_CLOSURE_FALSE = +KDE_USE_CLOSURE_TRUE = # +KDE_USE_FINAL_FALSE = +KDE_USE_FINAL_TRUE = # +KDE_USE_FPIE = -fPIE +KDE_USE_NMCHECK_FALSE = +KDE_USE_NMCHECK_TRUE = # +KDE_USE_PIE = -pie +KDE_XSL_STYLESHEET = /usr/share/apps/ksgmltools2/customization/kde-chunk.xsl +LDFLAGS = -Wl,-z,defs -Wl,--as-needed +LDFLAGS_AS_NEEDED = +LDFLAGS_NEW_DTAGS = +LIBCOMPAT = +LIBCRYPT = -lcrypt +LIBDL = -ldl +LIBJPEG = -ljpeg +LIBOBJS = +LIBPNG = -lpng -lz -lm +LIBPTHREAD = -lpthread +LIBREADLINE_LIBS = -lhistory -lreadline -lcurses +LIBRESOLV = -lresolv +LIBS = +LIBSM = -lSM -lICE +LIBSOCKET = +LIBTOOL = $(SHELL) $(top_builddir)/libtool --silent +LIBUCB = +LIBUSBCONFIG = yes +LIBUSB_CFLAGS = +LIBUSB_LIBS = -L/usr/lib -lusb +LIBUTIL = -lutil +LIBZ = -lz +LIB_KAB = -lkab +LIB_KABC = -lkabc +LIB_KDECORE = -lkdecore +LIB_KDED = +LIB_KDEPIM = -lkdepim +LIB_KDEPRINT = -lkdeprint +LIB_KDEUI = -lkdeui +LIB_KDNSSD = -lkdnssd +LIB_KFILE = -lkio +LIB_KFM = +LIB_KHTML = -lkhtml +LIB_KIMPROXY = -lkimproxy +LIB_KIO = -lkio +LIB_KJS = -lkjs +LIB_KNEWSTUFF = -lknewstuff +LIB_KPARTS = -lkparts +LIB_KSPELL = -lkspell +LIB_KSYCOCA = -lkio +LIB_KUNITTEST = -lkunittest +LIB_KUTILS = -lkutils +LIB_POLL = +LIB_QPE = +LIB_QT = -lqt-mt $(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM) -lpthread +LIB_SMB = -lsmb +LIB_X11 = -lX11 $(LIBSOCKET) +LIB_XEXT = -lXext +LIB_XRENDER = +LINUX_FALSE = # +LINUX_TRUE = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run makeinfo +MAKEKDEWIDGETS = +MCOPIDL = /usr/bin/mcopidl +MEINPROC = /usr/bin/meinproc +MOC = /usr/share/qt3/bin/moc +MSGFMT = /usr/bin/msgfmt +NOOPT_CFLAGS = -O0 +NOOPT_CXXFLAGS = -O0 +NULL_FALSE = +NULL_TRUE = # +OBJEXT = o +PACKAGE = piklab +PACKAGE_BUGREPORT = +PACKAGE_NAME = +PACKAGE_STRING = +PACKAGE_TARNAME = +PACKAGE_VERSION = +PATH_SEPARATOR = : +PERL = /usr/bin/perl +QTE_NORTTI = +QT_INCLUDES = -I/usr/share/qt3/include +QT_LDFLAGS = -L/usr/share/qt3/lib +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +TOPSUBDIRS = doc man po src +UIC = /usr/share/qt3/bin/uic -L $(kde_widgetdir) -nounload +UIC_TR = tr2i18n +USER_INCLUDES = +USER_LDFLAGS = +USE_EXCEPTIONS = -fexceptions +USE_RTTI = +USE_THREADS = +VERSION = 0.15.2 +WOVERLOADED_VIRTUAL = +XGETTEXT = /usr/bin/xgettext +XMKMF = +XMLLINT = /usr/bin/xmllint +X_EXTRA_LIBS = +X_INCLUDES = -I. +X_LDFLAGS = -L/usr/lib +X_PRE_LIBS = +X_RPATH = -R $(x_libraries) +ac_ct_CC = +ac_ct_CXX = +ac_ct_F77 = +all_includes = -I/usr/include/kde -I/usr/share/qt3/include -I. +all_libraries = -L/usr/share/qt3/lib -L/usr/lib +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__fastdepCXX_FALSE = # +am__fastdepCXX_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i486-pc-linux-gnu +build_alias = i486-linux-gnu +build_cpu = i486 +build_os = linux-gnu +build_vendor = pc +datadir = ${datarootdir} +datarootdir = ${prefix}/share +doc_SUBDIR_included_FALSE = # +doc_SUBDIR_included_TRUE = +docdir = ${datarootdir}/doc/${PACKAGE} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i486-pc-linux-gnu +host_alias = i486-linux-gnu +host_cpu = i486 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +include_ARTS_FALSE = # +include_ARTS_TRUE = +include_x11_FALSE = # +include_x11_TRUE = +includedir = ${prefix}/include +infodir = ${prefix}/share/info +install_sh = /home/miriam/piklab/piklab-0.15.2/admin/install-sh +kde_appsdir = ${datadir}/applnk +kde_bindir = ${exec_prefix}/bin +kde_confdir = ${datadir}/config +kde_datadir = ${datadir}/apps +kde_htmldir = ${datadir}/doc/HTML +kde_icondir = ${datadir}/icons +kde_includes = /usr/include/kde +kde_kcfgdir = ${datadir}/config.kcfg +kde_libraries = /usr/lib +kde_libs_htmldir = /usr/share/doc/kde/HTML +kde_libs_prefix = /usr +kde_locale = ${datadir}/locale +kde_mimedir = ${datadir}/mimelnk +kde_moduledir = ${libdir}/kde3 +kde_qtver = 3 +kde_servicesdir = ${datadir}/services +kde_servicetypesdir = ${datadir}/servicetypes +kde_sounddir = ${datadir}/sounds +kde_styledir = ${libdir}/kde3/plugins/styles +kde_templatesdir = ${datadir}/templates +kde_wallpaperdir = ${datadir}/wallpapers +kde_widgetdir = /usr/lib/kde3/plugins/designer +kdeinitdir = $(kde_moduledir) +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +man_SUBDIR_included_FALSE = # +man_SUBDIR_included_TRUE = +mandir = ${prefix}/share/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +pdfdir = ${docdir} +po_SUBDIR_included_FALSE = # +po_SUBDIR_included_TRUE = +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +qt_includes = /usr/share/qt3/include +qt_libraries = /usr/share/qt3/lib +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +src_SUBDIR_included_FALSE = # +src_SUBDIR_included_TRUE = +sysconfdir = ${prefix}/etc +target = i486-pc-linux-gnu +target_alias = +target_cpu = i486 +target_os = linux-gnu +target_vendor = pc +unsermake_enable_pch_FALSE = +unsermake_enable_pch_TRUE = # +x_includes = . +x_libraries = /usr/lib +xdg_appsdir = ${datadir}/applications/kde +xdg_directorydir = ${datadir}/desktop-directories +xdg_menudir = ${sysconfdir}/xdg/menus +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui +#>- all: all-recursive +#>+ 1 +all: docs-am all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-recursive +#>+ 1 +clean: kde-rpo-clean clean-recursive + +#>- clean-am: clean-generic clean-libtool mostlyclean-am +#>+ 1 +clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +KDE_DIST=Makefile.in sdcdb.pro Makefile.am + +#>+ 2 +docs-am: + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-recursive + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 3 +final: + $(MAKE) all-am + +#>+ 3 +final-install: + $(MAKE) install-am + +#>+ 3 +no-final: + $(MAKE) all-am + +#>+ 3 +no-final-install: + $(MAKE) install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/src/progs/sdcdb/Makefile.am b/src/progs/sdcdb/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/sdcdb/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/sdcdb/base/Makefile b/src/progs/sdcdb/base/Makefile new file mode 100644 index 0000000..a2e6af5 --- /dev/null +++ b/src/progs/sdcdb/base/Makefile @@ -0,0 +1,724 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 877 $ +# src/progs/sdcdb/base/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +srcdir = . +top_srcdir = ../../../.. + +pkgdatadir = $(datadir)/piklab +pkglibdir = $(libdir)/piklab +pkgincludedir = $(includedir)/piklab +top_builddir = ../../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c -p +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i486-pc-linux-gnu +host_triplet = i486-pc-linux-gnu +target_triplet = i486-pc-linux-gnu +subdir = src/progs/sdcdb/base +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libsdcdb_la_LIBADD = +am_libsdcdb_la_OBJECTS = sdcdb.lo sdcdb_debug.lo +#>- libsdcdb_la_OBJECTS = $(am_libsdcdb_la_OBJECTS) +#>+ 5 +libsdcdb_la_final_OBJECTS = libsdcdb_la.all_cpp.lo +libsdcdb_la_nofinal_OBJECTS = sdcdb.lo sdcdb_debug.lo\ +sdcdb_debug.moc.lo +libsdcdb_la_OBJECTS = $(libsdcdb_la_nofinal_OBJECTS) +#libsdcdb_la_OBJECTS = $(libsdcdb_la_final_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/admin/depcomp +am__depfiles_maybe = depfiles +#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 2 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ +#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +#>- $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 3 +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +CXXLD = $(CXX) +#>- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ +#>- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +#>+ 2 +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsdcdb_la_SOURCES) +DIST_SOURCES = $(libsdcdb_la_SOURCES) +ETAGS = etags +CTAGS = ctags +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run tar +AR = ar +ARTSCCONFIG = /usr/bin/artsc-config +AUTOCONF = $(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure +AUTODIRS = +AUTOHEADER = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run autoheader +AUTOMAKE = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run automake-1.9 +AWK = mawk +BSD_FALSE = +BSD_TRUE = # +CC = i486-linux-gnu-gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -O2 -Wall -g -O2 -Wformat-security -Wmissing-format-attribute +CONF_FILES = $(top_srcdir)/./admin/configure.in.min $(top_srcdir)/configure.in.in $(top_srcdir)/configure.in.mid +CPP = i486-linux-gnu-gcc -E +CPPFLAGS = -DQT_THREAD_SUPPORT -D_REENTRANT -L/usr/lib +CXX = i486-linux-gnu-g++ +CXXCPP = i486-linux-gnu-g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -Wno-long-long -Wundef -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -O2 -Wformat-security -Wmissing-format-attribute -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION +CYGPATH_W = echo +DCOPIDL = /usr/bin/dcopidl +DCOPIDL2CPP = /usr/bin/dcopidl2cpp +DCOPIDLNG = +DCOP_DEPENDENCIES = $(DCOPIDL) +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +ENABLE_PERMISSIVE_FLAG = -fpermissive +EXEEXT = +F77 = +FFLAGS = +FRAMEWORK_COREAUDIO = +GMSGFMT = /usr/bin/msgfmt +GREP = /bin/grep +HAVE_GCC_VISIBILITY = 0 +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} $(INSTALL_STRIP_FLAG) +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +KCFG_DEPENDENCIES = +KCONFIG_COMPILER = +KDECONFIG = /usr/bin/kde-config +KDE_CHECK_PLUGIN = $(KDE_PLUGIN) -rpath $(libdir) +KDE_EXTRA_RPATH = +KDE_INCLUDES = -I/usr/include/kde +KDE_LDFLAGS = -L/usr/lib +KDE_MT_LDFLAGS = +KDE_MT_LIBS = -lpthread +KDE_NO_UNDEFINED = -Wl,--no-undefined -Wl,--allow-shlib-undefined +KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS) +KDE_RPATH = -R $(libdir) -R $(kde_libraries) -R $(qt_libraries) -R $(x_libraries) +KDE_USE_CLOSURE_FALSE = +KDE_USE_CLOSURE_TRUE = # +KDE_USE_FINAL_FALSE = +KDE_USE_FINAL_TRUE = # +KDE_USE_FPIE = -fPIE +KDE_USE_NMCHECK_FALSE = +KDE_USE_NMCHECK_TRUE = # +KDE_USE_PIE = -pie +KDE_XSL_STYLESHEET = /usr/share/apps/ksgmltools2/customization/kde-chunk.xsl +LDFLAGS = -Wl,-z,defs -Wl,--as-needed +LDFLAGS_AS_NEEDED = +LDFLAGS_NEW_DTAGS = +LIBCOMPAT = +LIBCRYPT = -lcrypt +LIBDL = -ldl +LIBJPEG = -ljpeg +LIBOBJS = +LIBPNG = -lpng -lz -lm +LIBPTHREAD = -lpthread +LIBREADLINE_LIBS = -lhistory -lreadline -lcurses +LIBRESOLV = -lresolv +LIBS = +LIBSM = -lSM -lICE +LIBSOCKET = +LIBTOOL = $(SHELL) $(top_builddir)/libtool --silent +LIBUCB = +LIBUSBCONFIG = yes +LIBUSB_CFLAGS = +LIBUSB_LIBS = -L/usr/lib -lusb +LIBUTIL = -lutil +LIBZ = -lz +LIB_KAB = -lkab +LIB_KABC = -lkabc +LIB_KDECORE = -lkdecore +LIB_KDED = +LIB_KDEPIM = -lkdepim +LIB_KDEPRINT = -lkdeprint +LIB_KDEUI = -lkdeui +LIB_KDNSSD = -lkdnssd +LIB_KFILE = -lkio +LIB_KFM = +LIB_KHTML = -lkhtml +LIB_KIMPROXY = -lkimproxy +LIB_KIO = -lkio +LIB_KJS = -lkjs +LIB_KNEWSTUFF = -lknewstuff +LIB_KPARTS = -lkparts +LIB_KSPELL = -lkspell +LIB_KSYCOCA = -lkio +LIB_KUNITTEST = -lkunittest +LIB_KUTILS = -lkutils +LIB_POLL = +LIB_QPE = +LIB_QT = -lqt-mt $(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM) -lpthread +LIB_SMB = -lsmb +LIB_X11 = -lX11 $(LIBSOCKET) +LIB_XEXT = -lXext +LIB_XRENDER = +LINUX_FALSE = # +LINUX_TRUE = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run makeinfo +MAKEKDEWIDGETS = +MCOPIDL = /usr/bin/mcopidl +MEINPROC = /usr/bin/meinproc +MOC = /usr/share/qt3/bin/moc +MSGFMT = /usr/bin/msgfmt +NOOPT_CFLAGS = -O0 +NOOPT_CXXFLAGS = -O0 +NULL_FALSE = +NULL_TRUE = # +OBJEXT = o +PACKAGE = piklab +PACKAGE_BUGREPORT = +PACKAGE_NAME = +PACKAGE_STRING = +PACKAGE_TARNAME = +PACKAGE_VERSION = +PATH_SEPARATOR = : +PERL = /usr/bin/perl +QTE_NORTTI = +QT_INCLUDES = -I/usr/share/qt3/include +QT_LDFLAGS = -L/usr/share/qt3/lib +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +TOPSUBDIRS = doc man po src +UIC = /usr/share/qt3/bin/uic -L $(kde_widgetdir) -nounload +UIC_TR = tr2i18n +USER_INCLUDES = +USER_LDFLAGS = +USE_EXCEPTIONS = -fexceptions +USE_RTTI = +USE_THREADS = +VERSION = 0.15.2 +WOVERLOADED_VIRTUAL = +XGETTEXT = /usr/bin/xgettext +XMKMF = +XMLLINT = /usr/bin/xmllint +X_EXTRA_LIBS = +X_INCLUDES = -I. +X_LDFLAGS = -L/usr/lib +X_PRE_LIBS = +X_RPATH = -R $(x_libraries) +ac_ct_CC = +ac_ct_CXX = +ac_ct_F77 = +all_includes = -I/usr/include/kde -I/usr/share/qt3/include -I. +all_libraries = -L/usr/share/qt3/lib -L/usr/lib +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__fastdepCXX_FALSE = # +am__fastdepCXX_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i486-pc-linux-gnu +build_alias = i486-linux-gnu +build_cpu = i486 +build_os = linux-gnu +build_vendor = pc +datadir = ${datarootdir} +datarootdir = ${prefix}/share +doc_SUBDIR_included_FALSE = # +doc_SUBDIR_included_TRUE = +docdir = ${datarootdir}/doc/${PACKAGE} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i486-pc-linux-gnu +host_alias = i486-linux-gnu +host_cpu = i486 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +include_ARTS_FALSE = # +include_ARTS_TRUE = +include_x11_FALSE = # +include_x11_TRUE = +includedir = ${prefix}/include +infodir = ${prefix}/share/info +install_sh = /home/miriam/piklab/piklab-0.15.2/admin/install-sh +kde_appsdir = ${datadir}/applnk +kde_bindir = ${exec_prefix}/bin +kde_confdir = ${datadir}/config +kde_datadir = ${datadir}/apps +kde_htmldir = ${datadir}/doc/HTML +kde_icondir = ${datadir}/icons +kde_includes = /usr/include/kde +kde_kcfgdir = ${datadir}/config.kcfg +kde_libraries = /usr/lib +kde_libs_htmldir = /usr/share/doc/kde/HTML +kde_libs_prefix = /usr +kde_locale = ${datadir}/locale +kde_mimedir = ${datadir}/mimelnk +kde_moduledir = ${libdir}/kde3 +kde_qtver = 3 +kde_servicesdir = ${datadir}/services +kde_servicetypesdir = ${datadir}/servicetypes +kde_sounddir = ${datadir}/sounds +kde_styledir = ${libdir}/kde3/plugins/styles +kde_templatesdir = ${datadir}/templates +kde_wallpaperdir = ${datadir}/wallpapers +kde_widgetdir = /usr/lib/kde3/plugins/designer +kdeinitdir = $(kde_moduledir) +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +man_SUBDIR_included_FALSE = # +man_SUBDIR_included_TRUE = +mandir = ${prefix}/share/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +pdfdir = ${docdir} +po_SUBDIR_included_FALSE = # +po_SUBDIR_included_TRUE = +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +qt_includes = /usr/share/qt3/include +qt_libraries = /usr/share/qt3/lib +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +src_SUBDIR_included_FALSE = # +src_SUBDIR_included_TRUE = +sysconfdir = ${prefix}/etc +target = i486-pc-linux-gnu +target_alias = +target_cpu = i486 +target_os = linux-gnu +target_vendor = pc +unsermake_enable_pch_FALSE = +unsermake_enable_pch_TRUE = # +x_includes = . +x_libraries = /usr/lib +xdg_appsdir = ${datadir}/applications/kde +xdg_directorydir = ${datadir}/desktop-directories +xdg_menudir = ${sysconfdir}/xdg/menus +INCLUDES = -I$(top_srcdir)/src $(all_includes) +#>- METASOURCES = AUTO +noinst_LTLIBRARIES = libsdcdb.la +libsdcdb_la_LDFLAGS = $(all_libraries) +libsdcdb_la_SOURCES = sdcdb.cpp sdcdb_debug.cpp +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/base/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsdcdb.la: $(libsdcdb_la_OBJECTS) $(libsdcdb_la_DEPENDENCIES) + $(CXXLINK) $(libsdcdb_la_LDFLAGS) $(libsdcdb_la_OBJECTS) $(libsdcdb_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/sdcdb.Plo +include ./$(DEPDIR)/sdcdb_debug.Plo + +.cpp.o: + if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: + if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: + if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ +#>- mostlyclean-am +#>+ 2 +clean-am: clean-metasources clean-bcheck clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 3 +sdcdb_debug.moc.cpp: $(srcdir)/sdcdb_debug.h + $(MOC) $(srcdir)/sdcdb_debug.h -o sdcdb_debug.moc.cpp + +#>+ 2 +mocs: sdcdb_debug.moc.cpp + +#>+ 3 +clean-metasources: + -rm -f sdcdb_debug.moc.cpp + +#>+ 2 +KDE_DIST=base.pro Makefile.in sdcdb_debug.h Makefile.am + +#>+ 2 +docs-am: + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/base/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-am + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 11 +libsdcdb_la.all_cpp.cpp: $(srcdir)/Makefile.in sdcdb.cpp $(srcdir)/sdcdb_debug.cpp sdcdb_debug.moc.cpp + @echo 'creating libsdcdb_la.all_cpp.cpp ...'; \ + rm -f libsdcdb_la.all_cpp.files libsdcdb_la.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> libsdcdb_la.all_cpp.final; \ + for file in sdcdb.cpp sdcdb_debug.cpp sdcdb_debug.moc.cpp ; do \ + echo "#include \"$$file\"" >> libsdcdb_la.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libsdcdb_la.all_cpp.final; \ + done; \ + cat libsdcdb_la.all_cpp.final libsdcdb_la.all_cpp.files > libsdcdb_la.all_cpp.cpp; \ + rm -f libsdcdb_la.all_cpp.final libsdcdb_la.all_cpp.files + +#>+ 3 +clean-final: + -rm -f libsdcdb_la.all_cpp.cpp + +#>+ 3 +final: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_final_OBJECTS)" all-am + +#>+ 3 +final-install: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_final_OBJECTS)" install-am + +#>+ 3 +no-final: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_nofinal_OBJECTS)" all-am + +#>+ 3 +no-final-install: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_nofinal_OBJECTS)" install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/src/progs/sdcdb/base/Makefile.am b/src/progs/sdcdb/base/Makefile.am new file mode 100644 index 0000000..4ceb14f --- /dev/null +++ b/src/progs/sdcdb/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libsdcdb.la +libsdcdb_la_LDFLAGS = $(all_libraries) +libsdcdb_la_SOURCES = sdcdb.cpp sdcdb_debug.cpp diff --git a/src/progs/sdcdb/base/base.pro b/src/progs/sdcdb/base/base.pro new file mode 100644 index 0000000..c01db02 --- /dev/null +++ b/src/progs/sdcdb/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = sdcdb +HEADERS += sdcdb.h sdcdb_debug.h +SOURCES += sdcdb.cpp sdcdb_debug.cpp diff --git a/src/progs/sdcdb/base/sdcdb_debug.cpp b/src/progs/sdcdb/base/sdcdb_debug.cpp new file mode 100644 index 0000000..fcccf22 --- /dev/null +++ b/src/progs/sdcdb/base/sdcdb_debug.cpp @@ -0,0 +1,281 @@ +/*************************************************************************** + * 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 "gpsim_debug.h" + +#include <signal.h> +#include <qregexp.h> + +#include "devices/list/device_list.h" +#include "devices/pic/pic/pic_debug.h" +#include "devices/pic/base/pic_register.h" +#include "coff/base/coff.h" + +//---------------------------------------------------------------------------- +GPSim::Debugger::Debugger(Programmer &programmer) + : ::Debugger::PicBase(programmer), _nbBreakpoints(0) +{} + +bool GPSim::Debugger::internalInit() +{ + if ( !hardware()->execute("processor pic" + device()->name().lower(), true) ) return false; + if ( _inputType==PURL::Cod ) return hardware()->execute("load s " + _filename, true); + Q_ASSERT( _inputType==PURL::Hex ); + return hardware()->execute("load h " + _filename, true); +} + +bool GPSim::Debugger::internalRun() +{ + return hardware()->execute("run", false); +} + +bool GPSim::Debugger::hardHalt() +{ + log(Log::Warning, i18n("Failed to halt target: kill process.")); + _programmer.disconnectHardware(); + return true; +} + +bool GPSim::Debugger::softHalt(bool &success) +{ + success = hardware()->signal(SIGINT, true); + return true; +} + +bool GPSim::Debugger::internalStep() +{ + return hardware()->execute("step", true); +} + +bool GPSim::Debugger::setBreakpoints(const QValueList<Address> &list) +{ + for (uint i=0; i<_nbBreakpoints; i++) + if ( !hardware()->execute("clear " + QString::number(i), true) ) return false; + for (uint i=0; i<uint(list.count()); i++) + if ( !hardware()->execute("break e 0x" + toHex(list[i], nbChars(list[i].toUInt())), true) ) return false; + _nbBreakpoints = list.count(); + return true; +} + +bool GPSim::Debugger::internalReset() +{ + if ( _programmer.state()==::Programmer::Running && !halt() ) return false; + return hardware()->execute("reset", true); +} + +bool GPSim::Debugger::updateState() +{ + if ( hardware()->isReady() ) _programmer.setState(::Programmer::Halted); + else _programmer.setState(::Programmer::Running); + return true; +} + +bool GPSim::Debugger::findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const +{ + QRegExp rexp(pattern); + uint i = 0; + for (; i<uint(lines.count()); i++) { + int offset = 0; + for (;;) { + offset = rexp.search(lines[i], offset, QRegExp::CaretAtOffset); + if ( offset==-1 || rexp.cap(1)==label ) break; + offset += rexp.cap(0).length(); + } + if ( offset!=-1 ) break; + } + if ( i==uint(lines.count()) ) return false; + value = rexp.cap(2); + return true; +} + +bool GPSim::Debugger::readWreg(BitValue &value) +{ + // #### only known for version 4 and 11 + if ( hardware()->version()<=VersionData(0, 21, 7) || hardware()->version()>=VersionData(0, 22, 0) ) + return getRegister("W", value); + QStringList lines; + if ( !hardware()->execute("dump s", true, &lines) ) return false; + QString s; + if ( !findRegExp(lines, "^\\s*[0-9A-Fa-f]+\\s+(\\w+)\\s*=\\s*([0-9A-Fa-f]+)", "W", s) ) { + log(Log::Error, i18n("Error reading register \"W\"")); + return false; + } + value = fromHex(s, 0); + return true; +} + +bool GPSim::Debugger::getRegister(const QString &name, BitValue &value) +{ + QStringList lines; + QRegExp r; + if ( hardware()->version()<VersionData(0, 22, 0) ) { + if ( !hardware()->execute("x " + name, true, &lines) ) return false; + r.setPattern("\\w+\\s*[][\\w]+\\s*=\\s*(?:0x|)([0-9A-Fa-f]+)(?:\\W.*|)"); + } else { + if ( !hardware()->execute(name, true, &lines) ) return false; + r.setPattern("[^=]*=\\s*(?:0x|\\$)([0-9A-Fa-f]+)(?:\\W.*|)"); + } + uint i = 0; + for (; i<uint(lines.count()); i++) + if ( r.exactMatch(lines[i]) ) break; + if ( i==uint(lines.count()) ) { + log(Log::Error, i18n("Error reading register \"%1\"").arg(name)); + return false; + } + value = fromHex(r.cap(1), 0); + return true; +} + +bool GPSim::Debugger::getRegister(Address address, BitValue &value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString name = toHex(address, rdata.nbCharsAddress()); + if ( hardware()->version()<VersionData(0, 22, 0) ) return getRegister("0x" + name, value); + return getRegister(QString("ramData[$%1]").arg(name), value); +} + +bool GPSim::Debugger::readRegister(const Register::TypeData &data, BitValue &value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return readWreg(value); + if ( data.name()=="PC" ) return getRegister("pc", value); + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return readWreg(value); + if ( !name.isEmpty() ) return getRegister(name.lower(), value); + return getRegister(data.address(), value); +} + +bool GPSim::Debugger::setRegister(const QString &name, BitValue value) +{ + if ( hardware()->version()<VersionData(0, 22, 0) ) { + log(Log::Warning, i18n("Writing registers is not supported by this version of gpsim")); + return true; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("%1 = %2").arg(name).arg(toHexLabel(value, rdata.nbChars())); + return hardware()->execute(s, true); +} + +bool GPSim::Debugger::setRegister(Address address, BitValue value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("ramData[$%1]").arg(toHex(address, rdata.nbCharsAddress())); + return setRegister(s, value); +} + +bool GPSim::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return writeWreg(value); + if ( data.name()=="PC" ) { + log(Log::Warning, i18n("Writing PC is not supported by gpsim")); + return true; + } + Q_ASSERT(false); + return false; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString name = rdata.sfrNames[data.address()]; + if ( !name.isEmpty() ) return setRegister(name.lower(), value); + return setRegister(data.address(), value); +} + +bool GPSim::Debugger::writeWreg(BitValue value) +{ + return setRegister("W", value); +} + +bool GPSim::Debugger::updatePortStatus(uint index, QMap<uint, Device::PortBitData> &bits) +{ + for (uint i=0; i<Device::MAX_NB_PORT_BITS; i++) { + if ( !device()->registersData().hasPortBit(index, i) ) continue; + QString name = device()->registersData().portName(index).lower() + QString::number(i); + QStringList lines; + if ( !hardware()->execute("symbol " + name, true, &lines) ) return false; + QString pattern = "^(\\w+)=([^\\s])+\\s*", value; + if ( !findRegExp(lines, pattern, "bitState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading state of IO bit: %1").arg(name)); + return false; + } + switch (value[0].latin1()) { + case 'H': + case '1': bits[i].state = Device::High; break; + case 'L': + case '0': bits[i].state = Device::Low; break; + case 'W': bits[i].state = Device::WeakPullUp; break; + case 'w': bits[i].state = Device::WeakPullDown; break; + case 'Z': bits[i].state = Device::HighImpedance; break; + case 'X': bits[i].state = Device::Unknown; break; + default: + bits[i].state = Device::Unknown; + log(Log::Warning, i18n("Unknown state for IO bit: %1 (%2)").arg(name).arg(value)); + break; + } + if ( !findRegExp(lines, pattern, "Driving", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].driving = ( value[0]=='1' ); + if (bits[i].driving) { + if ( !findRegExp(lines, pattern, "drivingState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivingState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivenState = Device::IoUnknown; + } else { + if ( !findRegExp(lines, pattern, "drivenState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driven state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivenState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivingState = Device::IoUnknown; + } + } + return true; +} + +//---------------------------------------------------------------------------- +QString GPSim::Group::statusLabel() const +{ + return i18n("GPSim (4MHz)"); // #### FIXME: add config +} + +void GPSim::Group::initSupported() +{ + ProcessManager manager(0); + if ( !manager.start() ) return; + VersionData version; + if ( !manager.getVersion(version) ) return; + bool oldGpsim = ( version<VersionData(0, 21, 11) ); + if ( !manager.sendCommand("processor list", true) ) return; + QStringList devices = QStringList::split(" ", manager.process().sout().join(" ")); + for (uint i=0; i<uint(devices.count()); i++) { + QString s = devices[i].upper(); + if ( s.startsWith("PIC") ) s = s.mid(3); + const Pic::Data *data = static_cast<const Pic::Data *>(Device::lister().data(s)); + if (data) { + if ( data->architecture()==Pic::Architecture::P18F && oldGpsim ) continue; + addDevice(data->name(), data, ::Group::Tested); + } + } +} + +Programmer::Hardware *GPSim::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *GPSim::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/sdcdb/base/sdcdb_debug.h b/src/progs/sdcdb/base/sdcdb_debug.h new file mode 100644 index 0000000..55cda75 --- /dev/null +++ b/src/progs/sdcdb/base/sdcdb_debug.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2007 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 SDCDB_DEBUG_H +#define SDCDB_DEBUG_H + +#include "sdcdb.h" +#include "devices/pic/pic/pic_prog.h" +#include "devices/pic/pic/pic_debug.h" + +namespace SDCDB +{ +//----------------------------------------------------------------------------- +class Programmer : public ::Programmer::PicBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "sdcdb_programmer") {} + +private: + virtual VersionData minVersion() const { return VersionData(0, 8, 0); } + virtual bool verifyDeviceId() { return true; } + virtual bool checkErase() { return false; } + virtual bool internalErase(const Device::MemoryRange &) { return false; } + virtual bool checkRead() { return false; } + virtual bool internalRead(Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkProgram(const Device::Memory &) { return false; } + virtual bool internalProgram(const Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkVerify() { return false; } + virtual bool internalVerify(const Device::Memory &, const Device::MemoryRange &, ::Programmer::VerifyActions) { return false; } +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(Programmer &programmer); + virtual bool setBreakpoints(const QValueList<Address> &list); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + virtual bool updatePortStatus(uint index, QMap<uint, Device::PortBitData> &bits); + +private: + uint _nbBreakpoints; + + bool findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const; + bool getRegister(const QString &name, BitValue &value); + bool setRegister(const QString &name, BitValue value); + bool getRegister(Address address, BitValue &value); + bool setRegister(Address address, BitValue value); + Hardware *hardware() { return static_cast<Hardware *>(_programmer.hardware()); } + const Pic::Data *device() const { return static_cast<const Pic::Data *>(_programmer.device()); } + virtual bool internalInit(); + virtual bool updateState(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + bool readWreg(BitValue &value); + bool writeWreg(BitValue value); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "sdcdb"; } + virtual QString label() const { return i18n("SDCDB"); } + virtual QString statusLabel() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Debugger | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(Port::Type) const { return false; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 100; } + virtual bool isInputFileTypeSupported(PURL::FileType type) const { return ( type==PURL::Cod || type==PURL::Hex ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast<Programmer &>(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/sdcdb/sdcdb.pro b/src/progs/sdcdb/sdcdb.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/sdcdb/sdcdb.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/tbl_bootloader/Makefile.am b/src/progs/tbl_bootloader/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/tbl_bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/tbl_bootloader/base/Makefile.am b/src/progs/tbl_bootloader/base/Makefile.am new file mode 100644 index 0000000..60b11bc --- /dev/null +++ b/src/progs/tbl_bootloader/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtblbootloader.la +libtblbootloader_la_SOURCES = tbl_bootloader_data.cpp tbl_bootloader.cpp tbl_bootloader_prog.cpp +libtblbootloader_la_DEPENDENCIES = tbl_bootloader_data.cpp + +noinst_DATA = tbl_bootloader.xml +tbl_bootloader_data.cpp: ../xml/xml_tbl_bootloader_parser tbl_bootloader.xml + ../xml/xml_tbl_bootloader_parser +CLEANFILES = tbl_bootloader_data.cpp diff --git a/src/progs/tbl_bootloader/base/base.pro b/src/progs/tbl_bootloader/base/base.pro new file mode 100644 index 0000000..1ccb8e9 --- /dev/null +++ b/src/progs/tbl_bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = tbl_bootloader +HEADERS += tbl_bootloader_data.h tbl_bootloader.h tbl_bootloader_prog.h +SOURCES += tbl_bootloader_data.cpp tbl_bootloader.cpp tbl_bootloader_prog.cpp diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.cpp b/src/progs/tbl_bootloader/base/tbl_bootloader.cpp new file mode 100644 index 0000000..419ad86 --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.cpp @@ -0,0 +1,327 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "tbl_bootloader.h" + +#include "tbl_bootloader_data.h" +#include "progs/base/prog_config.h" + +//----------------------------------------------------------------------------- +Port::Serial::Speed TinyBootloader::Config::readSpeed() +{ + uint speed = readUIntEntry("port_speed", 19200); + for (uint i=0; i<Port::Serial::Nb_Speeds; i++) + if ( speed==Port::Serial::SPEED_VALUES[i] ) return Port::Serial::Speed(i); + return Port::Serial::S19200; +} +void TinyBootloader::Config::writeSpeed(Port::Serial::Speed speed) +{ + writeEntry("port_speed", Port::Serial::SPEED_VALUES[speed]); +} + +uint TinyBootloader::Config::readTimeout() +{ + return readUIntEntry("timeout", 300); +} +void TinyBootloader::Config::writeTimeout(uint timeout) +{ + writeEntry("timeout", timeout); +} + +uint TinyBootloader::Config::readRetries() +{ + return readUIntEntry("nb_retries", 5); +} +void TinyBootloader::Config::writeRetries(uint nb) +{ + writeEntry("nb_retries", nb); +} + +//----------------------------------------------------------------------------- +TinyBootloader::Hardware::Hardware(::Programmer::Base &base, const QString &portDevice) + : ::Bootloader::Hardware(base, new Port::Serial(portDevice, Port::Serial::NoProperty, base)) +{ + Config config; + _timeout = config.readTimeout(); + _retries = config.readRetries(); +} + +bool TinyBootloader::Hardware::openPort() +{ + if ( !port()->open() ) return false; + Config config; + if ( !port()->setMode(Port::Serial::IgnoreBreak | Port::Serial::IgnoreParity, + Port::Serial::ByteSize8 | Port::Serial::IgnoreControlLines, + config.readSpeed(), _timeout) ) + return false; + return true; +} + +bool TinyBootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + // #### possibly do hard (RTS) or soft reset (codes) + uchar uc = 0xC1; + if ( !port()->sendChar(uc, _timeout) ) return false; + if ( !port()->receiveChar((char &)_id, _timeout) ) return false; + if ( !waitReady(0) ) return false; + return true; +} + +bool TinyBootloader::Hardware::verifyDeviceId() +{ + uchar id = data(device().name()).id; + QValueVector<QString> list = _base.group().supportedDevices(); + QStringList devices; + for (uint i=0; i<uint(list.count()); i++) + if ( _id==data(list[i]).id ) devices.append(list[i]); + if ( _id!=id ) { + if ( devices.count()==0 ) log(Log::LineType::Error, i18n("Unknown id returned by bootloader (%1 read and %2 expected).").arg(toHexLabel(_id, 2)).arg(toHexLabel(id, 2))); + else log(Log::LineType::Error, i18n("Id returned by bootloader corresponds to other devices: %1 (%2 read and %3 expected).").arg(devices.join(" ")).arg(toHexLabel(_id, 2)).arg(toHexLabel(id, 2))); + // we can't ask for "continue anyway?" because bootloader can timeout... + return false; + } + log(Log::LineType::Information, " " + i18n("Bootloader identified device as: %1").arg(devices.join(" "))); + return true; +} + +bool TinyBootloader::Hardware::waitReady(bool *checkCRC) +{ + char c; + if ( !port()->receiveChar(c, _timeout) ) return false; + if ( c=='K' ) { + if (checkCRC) *checkCRC = true; + return true; + } + if (checkCRC) { + *checkCRC = false; + if ( c=='N' ) return true; + log(Log::LineType::Error, i18n("Received unexpected character ('%1' received; 'K' or 'N' expected).").arg(toPrintable(c, PrintAlphaNum))); + return true; + } + log(Log::LineType::Error, i18n("Received unexpected character ('%1' received; 'K' expected).").arg(toPrintable(c, PrintAlphaNum))); + return false; +} + +bool TinyBootloader::Hardware::sendChar(char c, uchar *crc) +{ + if (crc) *crc += c; + return port()->sendChar(c, 10*_timeout); +} + +bool TinyBootloader::Hardware::sendCodeAddress(uint address, uchar &crc) +{ + switch (device().architecture().type()) { + case Pic::Architecture::P16X: + if ( !sendChar(address >> 8, &crc) ) return false; // address high + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + break; + case Pic::Architecture::P18F: + if ( !sendChar(address >> 16, &crc) ) return false; // address upper + if ( !sendChar((address >> 8) & 0xFF, &crc) ) return false; // address high + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + break; + case Pic::Architecture::P30F: + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + if ( !sendChar((address >> 8) & 0xFF, &crc) ) return false; // address high + if ( !sendChar(address >> 16, &crc) ) return false; // address upper + break; + default: Q_ASSERT(false); return false; + } + return true; +} + +bool TinyBootloader::Hardware::endWrite(uchar crc, uint &retries, bool &ok) +{ + if ( !sendChar(-crc & 0xFF, 0) ) return false; + if ( !waitReady(&ok) ) return false; + if ( !ok ) { + if ( retries==0 ) { + log(Log::LineType::Error, i18n("Too many failures: bailing out.")); + return false; + } + retries--; + log(Log::LineType::Warning, i18n("CRC error from bootloader: retrying...")); + } + return true; +} + +bool TinyBootloader::Hardware::writeCode(const Device::Array &data, bool erase) +{ + uint nb = data.count() - 100; + Device::Array wdata(nb+4); + + // check that there is nothing on top of bootloader + for (uint i=nb; i<data.size(); i++) { + if ( data[i]==device().mask(Pic::MemoryRangeType::Code) ) continue; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + log(Log::LineType::Warning, " " + i18n("Code is present in bootloader reserved area (at address %1). It will be ignored.").arg(toHexLabel(address, device().nbCharsAddress()))); + break; + } + + // check first 4 instructions for "goto" and copy them + if (erase) { + for (uint i=0; i<4; i++) wdata[nb+i] = device().nopInstruction(); + } else { + bool ok = false; + for (uint i=0; i<4; i++) { + wdata[nb+i] = data[i]; + if ( !ok && device().isGotoInstruction(data[i]) ) { + ok = true; + if ( i==3 && device().gotoInstruction(0x0, false).count()==2 ) + log(Log::LineType::Warning, " " + i18n("Only the first word of the \"goto\" instruction is into the first four instructions.")); + } + } + if ( !ok ) log(Log::LineType::Warning, " " + i18n("No \"goto\" instruction in the first four instructions.")); + } + + // place "goto size-100" at reset vector + wdata[0] = device().nopInstruction(); // for icd2 + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * (nb+4); + Device::Array a = device().gotoInstruction(address, true); + for (uint i=0; i<a.size(); i++) wdata[1+i] = a[i]; + // copy the rest + for (uint i=4; i<nb; i++) wdata[i] = data[i]; + + uint retries = _retries, nbWords = 0x20; // 16F: 64 bytes (80 bytes reserved) ; 18F: 64 bytes ; 30F: 96 bytes + Q_ASSERT( (data.count()%nbWords)==0 ); + for (uint i=0; i<wdata.count(); i+=nbWords) { + if ( !erase ) { + bool write = false; + for (uint k=0; k<nbWords; k++) { + if ( wdata[i+k]==device().mask(Pic::MemoryRangeType::Code) ) continue; + write = true; + break; + } + if ( !write ) continue; // skip + } + for (;;) { + uchar crc = 0; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + if ( !sendCodeAddress(address, crc) ) return false; + uint nbw = device().nbBytesWord(Pic::MemoryRangeType::Code); + if ( !sendChar(nbw*nbWords, &crc) ) return false; + log(Log::DebugLevel::Normal, QString("write code memory at %1: %2 bytes").arg(toHexLabel(address, 4)).arg(2*nbWords)); + for(uint k=0; k<nbWords; k++) { + if ( !sendChar(wdata[i+k].byte(0), &crc) ) return false; // data low + if ( !sendChar(wdata[i+k].byte(1), &crc) ) return false; // data high + if ( nbw==3 && !sendChar(wdata[i+k].byte(2), &crc) ) return false; // upper byte + } + bool ok; + if ( !endWrite(crc, retries, ok) ) return false; + if (ok) break; + } + } + return true; +} + +bool TinyBootloader::Hardware::writeConfig(const Device::Array &data) +{ + if ( device().architecture()==Pic::Architecture::P16X ) return false; + uint retries = _retries; + for (uint i=0; i<data.count(); i++) { + for (;;) { + uchar crc = 0; + Address address = device().range(Pic::MemoryRangeType::Config).start + i; + switch (device().architecture().type()) { + case Pic::Architecture::P18F: + if ( !sendChar(0x80 | address.byte(2), &crc) ) return false; // address upper | flag + if ( !sendChar(address.byte(1), &crc) ) return false; // address high + if ( !sendChar(address.byte(0), &crc) ) return false; // address low + if ( !sendChar(1, &crc) ) return false; // nb bytes + if ( !sendChar(data[i].byte(0), &crc) ) return false; // data + break; + case Pic::Architecture::P30F: + if ( !sendChar(address.byte(0), &crc) ) return false; // address low + if ( !sendChar(address.byte(1), &crc) ) return false; // address high + if ( !sendChar(address.byte(2), &crc) ) return false; // address upper + if ( !sendChar(2, &crc) ) return false; // nb bytes + if ( !sendChar(data[i].byte(0), &crc) ) return false; // data low + if ( !sendChar(data[i].byte(1), &crc) ) return false; // data high + break; + default: Q_ASSERT(false); return false; + } + bool ok; + if ( !endWrite(crc, retries, ok) ) return false; + if (ok) break; + } + } + return true; +} + +bool TinyBootloader::Hardware::writeEeprom(const Device::Array &data) +{ + uint retries = _retries; + for (uint i=0; i<data.count(); i++) { + for (;;) { + uchar crc = 0; + Address address = device().range(Pic::MemoryRangeType::Config).start + i; + switch (device().architecture().type()) { + case Pic::Architecture::P16X: + if ( !sendChar(0x40, &crc) ) return false; // flag + if ( !sendChar(address.byte(0), &crc) ) return false; // address + if ( !sendChar(1, &crc) ) return false; // nb bytes + if ( !sendChar(data[i].byte(0), &crc) ) return false; // data + break; + case Pic::Architecture::P18F: + if ( !sendChar(0x40, &crc) ) return false; // flag + if ( !sendChar(address.byte(0), &crc) ) return false; // address + if ( !sendChar(data[i].byte(0), &crc) ) return false; // data + if ( !sendChar(0x00, &crc) ) return false; // dummy + break; + case Pic::Architecture::P30F: + if ( !sendChar(address.byte(0), &crc) ) return false; // address low + if ( !sendChar(address.byte(1), &crc) ) return false; // address high + if ( !sendChar(address.byte(2), &crc) ) return false; // address upper + if ( !sendChar(2, &crc) ) return false; // nb bytes + if ( !sendChar(data[i].byte(0), &crc) ) return false; // data low + if ( !sendChar(data[i].byte(1), &crc) ) return false; // data high + break; + default: Q_ASSERT(false); return false; + } + bool ok; + if ( !endWrite(crc, retries, ok) ) return false; + if (ok) break; + } + } + return true; +} + +bool TinyBootloader::Hardware::write(Pic::MemoryRangeType type, const Device::Array &data) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + if ( type==Pic::MemoryRangeType::Code ) return writeCode(data, false); + if ( type==Pic::MemoryRangeType::Config ) return writeConfig(data); + if ( type==Pic::MemoryRangeType::Eeprom ) return writeEeprom(data); + return false; +} + +//----------------------------------------------------------------------------- +bool TinyBootloader::DeviceSpecific::canWriteRange(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Eeprom || type==Pic::MemoryRangeType::Code ) return true; + if ( device().architecture()==Pic::Architecture::P18F && type==Pic::MemoryRangeType::Config ) return true; + return false; +} + +bool TinyBootloader::DeviceSpecific::doErase(bool) +{ + bool eeprom = readConfigEntry(::Programmer::Config::ProgramEeprom).toBool(); + if (eeprom) log(Log::LineType::Warning, " " + i18n("Only code and EEPROM will be erased.")); + else log(Log::LineType::Warning, " " + i18n("Only code will be erased.")); + if ( doEraseRange(Pic::MemoryRangeType::Code)==false ) return false; + if ( eeprom && doEraseRange(Pic::MemoryRangeType::Eeprom)==false ) return false; + return true; +} + +bool TinyBootloader::DeviceSpecific::doEraseRange(Pic::MemoryRangeType type) +{ + Pic::Memory memory(device()); + if ( type==Pic::MemoryRangeType::Code ) return static_cast<Hardware &>(hardware()).writeCode(memory.arrayForWriting(type), true); + return hardware().write(type, memory.arrayForWriting(type)); +} diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.h b/src/progs/tbl_bootloader/base/tbl_bootloader.h new file mode 100644 index 0000000..b6e759f --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2007 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 TBL_BOOTLOADER_H +#define TBL_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "progs/bootloader/base/bootloader_prog.h" +#include "common/port/serial.h" +#include "common/global/generic_config.h" + +namespace TinyBootloader +{ +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + Config() : GenericConfig("tiny_bootloader") {} + Port::Serial::Speed readSpeed(); + void writeSpeed(Port::Serial::Speed speed); + uint readTimeout(); // ms + void writeTimeout(uint timeout); // ms + uint readRetries(); + void writeRetries(uint nb); +}; + +//----------------------------------------------------------------------------- +class Hardware : public ::Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + Port::Serial *port() { return static_cast<Port::Serial *>(_port); } + bool verifyDeviceId(); + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType, Device::Array &, const ::Programmer::VerifyData *) { return false; } + bool writeCode(const Device::Array &data, bool erase); + bool writeConfig(const Device::Array &data); + bool writeEeprom(const Device::Array &data); + virtual bool internalConnectHardware(); + virtual bool openPort(); + +private: + uchar _id; + uint _timeout; // ms + uint _retries; + + bool waitReady(bool *checkCRC); + bool sendChar(char c, uchar *crc); + bool sendCodeAddress(uint address, uchar &crc); + bool endWrite(uchar crc, uint &retries, bool &ok); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return canWriteRange(type); } + virtual bool emulatedErase() const { return true; } + virtual bool canReadRange(Pic::MemoryRangeType) const { return false; } + virtual bool canWriteRange(Pic::MemoryRangeType type) const; + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.xml b/src/progs/tbl_bootloader/base/tbl_bootloader.xml new file mode 100644 index 0000000..bbad6dd --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.xml @@ -0,0 +1,70 @@ +<!-- ************************************************************************* --> +<!-- * Copyright (C) 2007 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. * --> +<!-- *************************************************************************/--> +<!DOCTYPE piklab> + +<type name="tbl_bootloader"> + <device name="16F873A" family="generic" id="0x32" /> + <device name="16F874A" family="generic" id="0x32" /> + <device name="16F876A" family="generic" id="0x31" /> + <device name="16F877A" family="generic" id="0x31" /> + <device name="16F87" family="generic" id="0x33" /> + <device name="16F88" family="generic" id="0x33" /> + + <device name="18F1220" family="generic" id="0x46" /> + <device name="18F1320" family="generic" id="0x45" /> + <device name="18F2220" family="generic" id="0x46" /> + <device name="18F2320" family="generic" id="0x45" /> + <device name="18F4220" family="generic" id="0x48" /> + <device name="18F4320" family="generic" id="0x47" /> + <device name="18F6720" family="generic" id="0x4A" /> + <device name="18F8720" family="generic" id="0x4A" /> + <device name="18F6620" family="generic" id="0x4B" /> + <device name="18F8620" family="generic" id="0x4B" /> + <device name="18F6520" family="generic" id="0x4C" /> + <device name="18F8520" family="generic" id="0x4C" /> + <device name="18F8680" family="generic" id="0x4D" /> + <device name="18F2525" family="generic" id="0x4E" /> + <device name="18F4525" family="generic" id="0x4E" /> + <device name="18F2620" family="generic" id="0x4F" /> + <device name="18F4620" family="generic" id="0x4F" /> + <device name="18F242" family="generic" id="0x42" /> + <device name="18F252" family="generic" id="0x41" /> + <device name="18F442" family="generic" id="0x42" /> + <device name="18F452" family="generic" id="0x41" /> + <device name="18F2420" family="generic" id="0x42" /> + <device name="18F2520" family="generic" id="0x41" /> + <device name="18F4420" family="generic" id="0x42" /> + <device name="18F4520" family="generic" id="0x41" /> + <device name="18F248" family="generic" id="0x44" /> + <device name="18F258" family="generic" id="0x43" /> + <device name="18F448" family="generic" id="0x44" /> + <device name="18F458" family="generic" id="0x43" /> + <device name="18F2480" family="generic" id="0x44" /> + <device name="18F2580" family="generic" id="0x43" /> + <device name="18F4480" family="generic" id="0x44" /> + <device name="18F4580" family="generic" id="0x43" /> + <device name="18F2455" family="generic" id="0x56" /> + <device name="18F2550" family="generic" id="0x55" /> + <device name="18F4455" family="generic" id="0x56" /> + <device name="18F4550" family="generic" id="0x55" /> + + <device name="30F2010" family="generic" id="0x70" /> + <device name="30F6014" family="generic" id="0x71" /> + <device name="30F6012" family="generic" id="0x71" /> + <device name="30F6013" family="generic" id="0x72" /> + <device name="30F6011" family="generic" id="0x72" /> + <device name="30F3013" family="generic" id="0x73" /> + <device name="30F3012" family="generic" id="0x73" /> + <device name="30F2012" family="generic" id="0x74" /> + <device name="30F2011" family="generic" id="0x74" /> + <device name="30F4011" family="generic" id="0x75" /> + <device name="30F4012" family="generic" id="0x75" /> + <device name="30F3010" family="generic" id="0x76" /> + <device name="30F3011" family="generic" id="0x76" /> +</type> diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_data.h b/src/progs/tbl_bootloader/base/tbl_bootloader_data.h new file mode 100644 index 0000000..51be528 --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_data.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (C) 2007 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 TBL_BOOTLOADER_DATA_H +#define TBL_BOOTLOADER_DATA_H + +namespace TinyBootloader +{ + struct Data { + uchar id; + }; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp new file mode 100644 index 0000000..22c831e --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "tbl_bootloader_prog.h" + +//----------------------------------------------------------------------------- +TinyBootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "tiny_bootloader_programmer_base") +{} diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h new file mode 100644 index 0000000..75b986d --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 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 TBL_BOOTLOADER_PROG_H +#define TBL_BOOTLOADER_PROG_H + +#include "tbl_bootloader.h" + +namespace TinyBootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public ::Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); + virtual bool verifyDeviceId() { return static_cast<Hardware &>(hardware()).verifyDeviceId(); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "tbl_bootloader"; } + virtual QString label() const { return i18n("Tiny Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::Serial; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast<const Pic::Data *>(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const { return new Hardware(base, hd.port.device); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/gui/Makefile.am b/src/progs/tbl_bootloader/gui/Makefile.am new file mode 100644 index 0000000..d10b944 --- /dev/null +++ b/src/progs/tbl_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtblbootloaderui.la +libtblbootloaderui_la_LDFLAGS = $(all_libraries) +libtblbootloaderui_la_SOURCES = tbl_bootloader_ui.cpp diff --git a/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp new file mode 100644 index 0000000..5b576b9 --- /dev/null +++ b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "tbl_bootloader_ui.h" + +#include "progs/tbl_bootloader/base/tbl_bootloader.h" +#include "common/port/serial.h" + +//----------------------------------------------------------------------------- +TinyBootloader::ConfigWidget::ConfigWidget(const::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + + QLabel *label = new QLabel(i18n("Port Speed:"), this); + addWidget(label, row,row, 0,0); + _speed = new KComboBox(this); + for (uint i=0; i<Port::Serial::Nb_Speeds; i++) { + if ( Port::Serial::SPEED_VALUES[i]==0 || !Port::Serial::SPEED_DATA[i].supported ) continue; + _speed->insertItem(QString::number(Port::Serial::SPEED_VALUES[i])); + } + addWidget(_speed, row,row, 1,1); + row++; + + label = new QLabel(i18n("Timeout (ms):"), this); + addWidget(label, row,row, 0,0); + _timeout = new KIntNumInput(this); + _timeout->setMinValue(0); + addWidget(_timeout, row,row, 1,1); + row++; + + label = new QLabel(i18n("No of Retries:"), this); + addWidget(label, row,row, 0,0); + _retries = new KIntNumInput(this); + _retries->setMinValue(0); + addWidget(_retries, row,row, 1,1); + row++; +} + +void TinyBootloader::ConfigWidget::saveConfig() +{ + Config config; + uint k = 0; + for (uint i=0; i<Port::Serial::Nb_Speeds; i++) { + if ( Port::Serial::SPEED_VALUES[i]==0 || !Port::Serial::SPEED_DATA[i].supported ) continue; + if ( uint(_speed->currentItem())==k ) { + config.writeSpeed(Port::Serial::Speed(i)); + break; + } + k++; + } + config.writeTimeout(_timeout->value()); + config.writeRetries(_retries->value()); +} + +void TinyBootloader::ConfigWidget::loadConfig() +{ + Config config; + Port::Serial::Speed speed = config.readSpeed(); + uint k = 0; + for (uint i=0; i<Port::Serial::Nb_Speeds; i++) { + if ( Port::Serial::SPEED_VALUES[i]==0 || !Port::Serial::SPEED_DATA[i].supported ) continue; + if ( i==uint(speed) ) break; + k++; + } + _speed->setCurrentItem(k); + _timeout->setValue(config.readTimeout()); + _retries->setValue(config.readRetries()); +} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *TinyBootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent); +} diff --git a/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h new file mode 100644 index 0000000..d0285af --- /dev/null +++ b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 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 TBL_BOOTLOADER_UI_H +#define TBL8BOOTLOADER_UI_H + +#include <kcombobox.h> +#include <knuminput.h> + +#include "progs/bootloader/gui/bootloader_ui.h" + +//----------------------------------------------------------------------------- +namespace TinyBootloader +{ +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual void loadConfig(); + virtual void saveConfig(); + +private: + KIntNumInput *_timeout, *_retries; + KComboBox *_type, *_speed; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/tbl_bootloader.pro b/src/progs/tbl_bootloader/tbl_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/tbl_bootloader/tbl_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/tbl_bootloader/xml/Makefile.am b/src/progs/tbl_bootloader/xml/Makefile.am new file mode 100644 index 0000000..609ca90 --- /dev/null +++ b/src/progs/tbl_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_tbl_bootloader_parser +xml_tbl_bootloader_parser_SOURCES = xml_tbl_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_tbl_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_tbl_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/tbl_bootloader/xml/xml.pro b/src/progs/tbl_bootloader/xml/xml.pro new file mode 100644 index 0000000..a7d488a --- /dev/null +++ b/src/progs/tbl_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_tbl_bootloader_parser +SOURCES += xml_tbl_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_tbl_bootloader_parser +unix:QMAKE_CLEAN += ../base/tbl_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_tbl_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\tbl_bootloader_data.cpp diff --git a/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp b/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp new file mode 100644 index 0000000..62ed806 --- /dev/null +++ b/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "xml_to_data/prog_xml_to_data.h" + +#include "progs/tbl_bootloader/base/tbl_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace TinyBootloader +{ + +class XmlToData : public Programmer::XmlToData<Data> +{ +public: + XmlToData() : Programmer::XmlToData<Data>("tbl_bootloader", "TinyBootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void TinyBootloader::XmlToData::parseData(QDomElement element, Data &data) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast<const Pic::Data *>(ddata); + if ( !pdata->hasFeature(Pic::Feature::USART) ) qFatal("device does not have USART"); + bool ok; + data.id = fromHexLabel(element.attribute("id"), 2, &ok); + if ( !ok ) qFatal("Invalid \"id\" tag"); +} + +void TinyBootloader::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << data.id; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(TinyBootloader::XmlToData) |