summaryrefslogtreecommitdiffstats
path: root/src/progs/base
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 18:42:24 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 18:42:24 +0000
commitf508189682b6fba62e08feeb1596f682bad5fff9 (patch)
tree28aeb0e6c19386c385c1ce5edf8a92c1bca15281 /src/progs/base
downloadpiklab-f508189682b6fba62e08feeb1596f682bad5fff9.tar.gz
piklab-f508189682b6fba62e08feeb1596f682bad5fff9.zip
Added KDE3 version of PikLab
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/piklab@1095639 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/progs/base')
-rw-r--r--src/progs/base/Makefile.am10
-rw-r--r--src/progs/base/base.pro8
-rw-r--r--src/progs/base/debug_config.cpp14
-rw-r--r--src/progs/base/debug_config.h24
-rw-r--r--src/progs/base/generic_debug.cpp111
-rw-r--r--src/progs/base/generic_debug.h90
-rw-r--r--src/progs/base/generic_prog.cpp402
-rw-r--r--src/progs/base/generic_prog.h163
-rw-r--r--src/progs/base/hardware_config.cpp97
-rw-r--r--src/progs/base/hardware_config.h61
-rw-r--r--src/progs/base/prog_config.cpp78
-rw-r--r--src/progs/base/prog_config.h42
-rw-r--r--src/progs/base/prog_group.cpp62
-rw-r--r--src/progs/base/prog_group.h69
-rw-r--r--src/progs/base/prog_specific.cpp51
-rw-r--r--src/progs/base/prog_specific.h61
16 files changed, 1343 insertions, 0 deletions
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