diff options
Diffstat (limited to 'src/progs/base')
-rw-r--r-- | src/progs/base/Makefile.am | 10 | ||||
-rw-r--r-- | src/progs/base/base.pro | 8 | ||||
-rw-r--r-- | src/progs/base/debug_config.cpp | 14 | ||||
-rw-r--r-- | src/progs/base/debug_config.h | 24 | ||||
-rw-r--r-- | src/progs/base/generic_debug.cpp | 111 | ||||
-rw-r--r-- | src/progs/base/generic_debug.h | 90 | ||||
-rw-r--r-- | src/progs/base/generic_prog.cpp | 402 | ||||
-rw-r--r-- | src/progs/base/generic_prog.h | 163 | ||||
-rw-r--r-- | src/progs/base/hardware_config.cpp | 97 | ||||
-rw-r--r-- | src/progs/base/hardware_config.h | 61 | ||||
-rw-r--r-- | src/progs/base/prog_config.cpp | 78 | ||||
-rw-r--r-- | src/progs/base/prog_config.h | 42 | ||||
-rw-r--r-- | src/progs/base/prog_group.cpp | 62 | ||||
-rw-r--r-- | src/progs/base/prog_group.h | 69 | ||||
-rw-r--r-- | src/progs/base/prog_specific.cpp | 51 | ||||
-rw-r--r-- | src/progs/base/prog_specific.h | 61 |
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 |