summaryrefslogtreecommitdiffstats
path: root/src/progs/icd2/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/icd2/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/icd2/base')
-rw-r--r--src/progs/icd2/base/Makefile.am13
-rw-r--r--src/progs/icd2/base/base.pro8
-rw-r--r--src/progs/icd2/base/icd.cpp94
-rw-r--r--src/progs/icd2/base/icd.h74
-rw-r--r--src/progs/icd2/base/icd2.cpp517
-rw-r--r--src/progs/icd2/base/icd2.h95
-rw-r--r--src/progs/icd2/base/icd2.xml214
-rw-r--r--src/progs/icd2/base/icd2_data.h42
-rw-r--r--src/progs/icd2/base/icd2_debug.cpp348
-rw-r--r--src/progs/icd2/base/icd2_debug.h89
-rw-r--r--src/progs/icd2/base/icd2_debug_specific.cpp255
-rw-r--r--src/progs/icd2/base/icd2_debug_specific.h98
-rw-r--r--src/progs/icd2/base/icd2_prog.cpp142
-rw-r--r--src/progs/icd2/base/icd2_prog.h84
-rw-r--r--src/progs/icd2/base/icd2_serial.cpp66
-rw-r--r--src/progs/icd2/base/icd2_serial.h41
-rw-r--r--src/progs/icd2/base/icd2_usb.cpp174
-rw-r--r--src/progs/icd2/base/icd2_usb.h63
-rw-r--r--src/progs/icd2/base/icd2_usb_firmware.cpp613
-rw-r--r--src/progs/icd2/base/icd_prog.cpp39
-rw-r--r--src/progs/icd2/base/icd_prog.h40
-rw-r--r--src/progs/icd2/base/microchip.cpp11
-rw-r--r--src/progs/icd2/base/microchip.h19
-rw-r--r--src/progs/icd2/base/promate2.xml235
24 files changed, 3374 insertions, 0 deletions
diff --git a/src/progs/icd2/base/Makefile.am b/src/progs/icd2/base/Makefile.am
new file mode 100644
index 0000000..9350219
--- /dev/null
+++ b/src/progs/icd2/base/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libicd2.la
+libicd2_la_SOURCES = microchip.cpp icd2.cpp icd2_prog.cpp icd2_serial.cpp \
+ icd2_usb.cpp icd2_usb_firmware.cpp icd2_data.cpp icd2_debug.cpp icd.cpp \
+ icd_prog.cpp icd2_debug_specific.cpp
+libicd2_la_DEPENDENCIES = icd2_data.cpp
+
+noinst_DATA = icd2.xml
+icd2_data.cpp: ../xml/xml_icd2_parser icd2.xml
+ ../xml/xml_icd2_parser
+CLEANFILES = icd2_data.cpp
diff --git a/src/progs/icd2/base/base.pro b/src/progs/icd2/base/base.pro
new file mode 100644
index 0000000..6ca2f2d
--- /dev/null
+++ b/src/progs/icd2/base/base.pro
@@ -0,0 +1,8 @@
+STOPDIR = ../../../..
+include($${STOPDIR}/lib.pro)
+
+TARGET = icd2
+HEADERS += microchip.h icd.h icd_prog.h icd2.h icd2_data.h \
+ icd2_prog.h icd2_debug_specific.h icd2_debug.h icd2_serial.h icd2_usb.h
+SOURCES += microchip.cpp icd.cpp icd_prog.cpp icd2.cpp icd2_data.cpp \
+ icd2_prog.cpp icd2_debug_specific.cpp icd2_debug.cpp icd2_serial.cpp icd2_usb.cpp icd2_usb_firmware.cpp
diff --git a/src/progs/icd2/base/icd.cpp b/src/progs/icd2/base/icd.cpp
new file mode 100644
index 0000000..bfb1129
--- /dev/null
+++ b/src/progs/icd2/base/icd.cpp
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd.h"
+
+#include "common/global/global.h"
+#include "common/common/misc.h"
+#include "common/port/port_base.h"
+
+//-----------------------------------------------------------------------------
+bool Icd::DeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ data.resize(device().nbWords(type));
+ if ( vdata==0 ) return hardware().readMemory(type, 0, data, vdata);
+ bool only = ( vdata->actions & ::Programmer::OnlyProgrammedVerify );
+ const Device::Array tmp = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type);
+ uint wordOffset;
+ Device::Array pdata = prepareRange(type, tmp, !only, wordOffset);
+ return hardware().readMemory(type, wordOffset, pdata, vdata);
+}
+
+Device::Array Icd::DeviceSpecific::prepareRange(Pic::MemoryRangeType type, const Device::Array &data,
+ bool force, uint &wordOffset)
+{
+ if ( type!=Pic::MemoryRangeType::Code ) {
+ wordOffset = 0;
+ return data;
+ }
+ wordOffset = (force ? 0 : findNonMaskStart(type, data));
+ uint nbWords = 0;
+ if ( wordOffset!=data.count() ) {
+ uint end = (force ? data.count() : findNonMaskEnd(type, data));
+ nbWords = end - wordOffset + 1;
+ log(Log::DebugLevel::Normal, QString(" start=%1 nbWords=%2 total=%3 force=%4")
+ .arg(toHexLabel(wordOffset, device().nbCharsAddress())).arg(toHexLabel(nbWords, device().nbCharsAddress()))
+ .arg(toHexLabel(data.count(), device().nbCharsAddress())).arg(force ? "true" : "false"));
+ }
+ _base.progressMonitor().addTaskProgress(data.count()-nbWords);
+ return data.mid(wordOffset, nbWords);
+}
+
+bool Icd::DeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ Q_ASSERT( data.count()==device().nbWords(type) );
+
+ uint nb = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code);
+ if ( device().architecture()==Pic::Architecture::P18J && type==Pic::MemoryRangeType::Config ) {
+ Q_ASSERT( data.count()%2==0 );
+ int delta = nb - data.count()/2; // config memory words contains 1 byte
+ Q_ASSERT( delta>=0 );
+ Device::Array rdata(delta);
+ uint wordOffset = device().nbWords(Pic::MemoryRangeType::Code) - delta;
+ if ( !hardware().readMemory(Pic::MemoryRangeType::Code, wordOffset, rdata, 0) ) return false;
+ Device::Array pdata(nb);
+ for (uint i=0; i<uint(delta); i++) pdata[i] = rdata[i];
+ for (uint i=delta; i<nb; i++) {
+ pdata[i] = data[2*(i-delta)];
+ pdata[i] |= data[2*(i-delta)+1] << 8;
+ }
+ return hardware().writeMemory(Pic::MemoryRangeType::Code, wordOffset, pdata);
+ }
+
+ uint wordOffset;
+ Device::Array pdata = prepareRange(type, data, force, wordOffset);
+ if ( device().architecture()==Pic::Architecture::P18J && type==Pic::MemoryRangeType::Code ) {
+ uint end = wordOffset + pdata.size();
+ if ( end>=device().nbWords(Pic::MemoryRangeType::Code) ) {
+ Device::Array rdata(device().nbWords(Pic::MemoryRangeType::Config));
+ if ( !hardware().readMemory(Pic::MemoryRangeType::Code, device().nbWords(Pic::MemoryRangeType::Code), rdata, 0) ) return false;
+ uint n = rdata.count() / 2;
+ for (uint i=0; i<n; i++) {
+ pdata[pdata.size() - n + i] = rdata[2*i];
+ pdata[pdata.size() - n + i] |= rdata[2*i+1] << 8;
+ }
+ }
+ }
+ return hardware().writeMemory(type, wordOffset, pdata);
+}
+
+bool Icd::DeviceSpecific::doErase(bool)
+{
+ if ( device().architecture()==Pic::Architecture::P18J ) { // ### also true for others ?
+ Device::Array data(device().nbWords(Pic::MemoryRangeType::Config));
+ for (uint i=0; i<data.size(); i++) data[i] = device().config()._words[i].wmask;
+ if ( !doWrite(Pic::MemoryRangeType::Config, data, true) ) return false;
+ }
+ return hardware().eraseAll();
+}
diff --git a/src/progs/icd2/base/icd.h b/src/progs/icd2/base/icd.h
new file mode 100644
index 0000000..9a65755
--- /dev/null
+++ b/src/progs/icd2/base/icd.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD_H
+#define ICD_H
+
+#include "microchip.h"
+#include "devices/pic/prog/pic_prog.h"
+#include "devices/pic/pic/pic_memory.h"
+
+namespace Icd
+{
+//-----------------------------------------------------------------------------
+class Hardware : public ::Programmer::PicHardware
+{
+public:
+ Hardware(::Programmer::Base &base, Port::Base *port) : ::Programmer::PicHardware(base, port, QString::null) {}
+// initialization
+ virtual bool uploadFirmware(const Pic::Memory &memory) = 0;
+ virtual bool setTarget() = 0;
+
+// status
+ virtual bool getFirmwareVersion(VersionData &version) = 0;
+ virtual bool setTargetPowerOn(bool) { return true; }
+
+// programming
+ virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata) = 0;
+ virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) = 0;
+ virtual bool eraseAll() = 0;
+
+// debugging
+ virtual bool readRegister(Address address, BitValue &value, uint nbBytes) = 0;
+ virtual bool writeRegister(Address address, BitValue value, uint nbBytes) = 0;
+ virtual bool resumeRun() = 0;
+ virtual bool step() = 0;
+ virtual bool haltRun() = 0;
+ virtual BitValue getProgramCounter() = 0;
+
+protected:
+ QString _rx;
+ virtual bool internalConnect(const QString &mode) = 0;
+ virtual QString receivedData() const = 0;
+ virtual bool internalConnectHardware() { return internalConnect("U"); }
+};
+
+//-----------------------------------------------------------------------------
+class DeviceSpecific : public ::Programmer::PicDeviceSpecific
+{
+public:
+ DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {}
+ virtual bool canEraseAll() const { return true; }
+ virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; }
+ virtual bool canReadRange(Pic::MemoryRangeType) const { return true; }
+ virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; }
+ Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); }
+ virtual bool setPowerOff() { return false; }
+ virtual bool setPowerOn() { return false; }
+ virtual bool setTargetPowerOn(bool on) { return hardware().setTargetPowerOn(on); }
+ virtual bool doEraseRange(Pic::MemoryRangeType) { return false; }
+ virtual bool doErase(bool);
+ virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata);
+ Device::Array prepareRange(Pic::MemoryRangeType type, const Device::Array &data, bool force, uint &wordOffset);
+ virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2.cpp b/src/progs/icd2/base/icd2.cpp
new file mode 100644
index 0000000..375fc60
--- /dev/null
+++ b/src/progs/icd2/base/icd2.cpp
@@ -0,0 +1,517 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2.h"
+
+#include "common/global/global.h"
+#include "common/common/misc.h"
+#include "common/port/port_base.h"
+#include "icd2_data.h"
+#include "icd2_usb.h"
+
+//-----------------------------------------------------------------------------
+const uchar Icd2::TARGET_MODE_VALUES[Pic::Nb_TargetModes] = {
+ 0x00, // stopped
+ 0x01, // running
+ 0x02 // in programming
+};
+
+const char * const Icd2::RESET_MODE_VALUES[Pic::Nb_ResetModes] = {
+ "00", // reset held
+ "01" // reset released
+};
+
+//-----------------------------------------------------------------------------
+const Icd2::Hardware::VoltageTypeData Icd2::Hardware::VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes] = {
+ { "37", 0.07988 }, // icd Vpp
+ { "34", 0.03908 }, // target Vdd
+ { "35", 0.07988 }, // target Vpp
+};
+
+const char * const Icd2::Hardware::WRITE_MODE_VALUES[Pic::Nb_WriteModes] = {
+ "00", // write only
+ "01" // erase then write
+};
+
+const int Icd2::TestData::RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1] = {
+ 0x00, // pass
+ 0x01, // low
+ 0x80, // high
+ -2, // not used
+ -1
+};
+
+const char * const Icd2::TestData::VOLTAGE_LABELS[Nb_VoltageTypes] = {
+ I18N_NOOP("Target Vdd"), I18N_NOOP("Module Vpp"), I18N_NOOP("MCLR ground"),
+ I18N_NOOP("MCLR Vdd"), I18N_NOOP("MCLR Vpp")
+};
+
+Icd2::TestData::TestData()
+{
+ for (uint k=0; k<Nb_VoltageTypes; k++) _voltages[k] = -1;
+}
+
+Icd2::TestData::TestData(const QString &rx)
+{
+ for (uint k=0; k<Nb_VoltageTypes; k++)
+ _voltages[k] = fromHex(rx.mid(5 + 2*k, 2), 0);
+}
+
+bool Icd2::TestData::pass() const
+{
+ for (uint k=0; k<Nb_VoltageTypes; k++)
+ if ( _voltages[k]!=RESULT_TYPE_VALUES[::Programmer::Pass] ) return false;
+ return true;
+}
+
+QString Icd2::TestData::result(VoltageType type) const
+{
+ for (uint i=0; i<=(::Programmer::Nb_ResultTypes); i++)
+ if ( _voltages[type]==RESULT_TYPE_VALUES[i] ) return i18n(::Programmer::RESULT_TYPE_LABELS[i]);
+ return toHex(_voltages[type], 2);
+}
+
+QString Icd2::TestData::pretty(VoltageType type) const
+{
+ return i18n(VOLTAGE_LABELS[type]) + "=" + result(type);
+}
+
+//-----------------------------------------------------------------------------
+const char *Icd2::Hardware::readCommand(Pic::MemoryRangeType type) const
+{
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Code: return "47";
+ case Pic::MemoryRangeType::Eeprom: return "48";
+ case Pic::MemoryRangeType::Config:
+ if ( device().architecture()==Pic::Architecture::P18J ) return "47";
+ return "49";
+ case Pic::MemoryRangeType::UserId: return "4A";
+ case Pic::MemoryRangeType::DeviceId:
+ if ( device().architecture()==Pic::Architecture::P30F ) return "49";
+ return "4A";
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::CalBackup:
+ if ( device().architecture()==Pic::Architecture::P16X ) return "49"; // ?
+ return "47"; // for baseline only ?
+ case Pic::MemoryRangeType::DebugVector: return "40";
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return 0;
+}
+
+const char *Icd2::Hardware::writeCommand(Pic::MemoryRangeType type) const
+{
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Code: return "43";
+ case Pic::MemoryRangeType::Eeprom: return "44";
+ case Pic::MemoryRangeType::Config:
+ if ( device().architecture()==Pic::Architecture::P18J ) return "43";
+ return "45";
+ case Pic::MemoryRangeType::UserId: return "46";
+ case Pic::MemoryRangeType::DeviceId: break;
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::CalBackup:
+ if ( device().architecture()==Pic::Architecture::P16X ) return "45"; // ?
+ return "43"; // for baseline only ?
+ case Pic::MemoryRangeType::DebugVector: return "41";
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return 0;
+}
+
+bool Icd2::Hardware::uploadFirmware(const Pic::Memory &memory)
+{
+ if ( !internalConnect("V") ) return false;
+ log(Log::LineType::Information, " Uploading firmware to ICD2...");
+ uint start = 0x0004, size = 0x1BFB;
+ QString cmd = "10" + toHex(start, 4) + toHex(size, 4);
+ if ( !command(cmd, 0) ) return false;
+ uint nbBytesWord = memory.device().nbBytesWord(Pic::MemoryRangeType::Code); // should be 2 for 16F876
+ Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Code);
+ if ( !writeBlock(nbBytesWord, data, start, size) ) return false;
+ if ( !receiveResponse(cmd, 0, false) ) return false;
+ if ( !internalConnect("U") ) return false;
+ return true;
+}
+
+bool Icd2::Hardware::setTarget()
+{
+ log(Log::DebugLevel::Normal, " Set target");
+ // set target family
+ const Icd2::Data &d = data(device().name());
+ if ( !command(QString("2A") + toHex(d.famid, 2), 0) ) return false;
+ // set code range end
+ Address end = device().range(Pic::MemoryRangeType::Code).end;
+ if ( device().range(Pic::MemoryRangeType::Cal).start==end ) end += 1;
+ if ( !command("06" + toHex(end, 6), 0) ) return false;
+ return true;
+}
+
+bool Icd2::Hardware::setup()
+{
+ // ??
+ if ( device().architecture()==Pic::Architecture::P30F )
+ if ( !command("0900", 0) ) return false;
+
+ // ??
+ _port->send("$7F00\x0D", 6);
+ QString s;
+ if ( !_port->receive(2, s) ) return false;
+ if ( s!="02" ) {
+ log(Log::LineType::Error, i18n("Unexpected answer ($7F00) from ICD2 (%1).").arg(s));
+ return false;
+ }
+
+ // ??
+ if ( !command("08", 2) ) return false;
+ if ( _rx.mid(5, 2)!="00" ) {
+ log(Log::LineType::Error, i18n("Unexpected answer (08) from ICD2 (%1).").arg(_rx));
+ return false;
+ }
+
+ return !hasError();
+}
+
+bool Icd2::Hardware::sendCommand(const QString &s)
+{
+ //format: <LLXX....CC>
+ QString cs = s.upper();
+ QString tx = "<";
+ tx += toHex(cs.length() + 6, 2);
+ tx += cs;
+ uchar chk = tx[1].latin1() + tx[2].latin1();
+ for (uint i=0; i<uint(s.length()); i++) chk += cs[i].latin1();
+ tx += toHex(chk, 2);
+ tx += '>';
+ log(Log::DebugLevel::Extra, QString("send command: '%1'").arg(tx));
+ QByteArray a = toAscii(tx);
+ return _port->send(a.data(), a.count());
+}
+
+bool Icd2::Hardware::receiveResponse(const QString &command, uint responseSize, bool poll)
+{
+ // format: [LLXX...CC]
+ uint size = responseSize + 8;
+ if ( poll && _port->type()==PortType::USB ) {
+ if ( !static_cast<USBPort *>(_port)->poll(size, _rx) ) return false;
+ } else if ( !_port->receive(size, _rx, 180000) ) return false; // is 3 minutes enough ?? (we should really have an abort button here...)
+ log(Log::DebugLevel::Extra, QString("received answer: '%1'").arg(_rx));
+ if ( size!=fromHex(_rx.mid(1, 2), 0) ) {
+ log(Log::LineType::Error, i18n("Received length too short."));
+ return false;
+ }
+ if ( uint(_rx.length())!=size ) {
+ log(Log::LineType::Error, i18n("Received string too short."));
+ return false;
+ }
+ if ( _rx[0]!='[' || _rx[size-1]!=']' ) {
+ log(Log::LineType::Error, i18n("Malformed string received \"%1\"").arg(_rx));
+ return false;
+ }
+ if ( command.mid(0, 2)!=_rx.mid(3, 2) ) {
+ log(Log::LineType::Error, i18n("Wrong return value (\"%1\"; was expecting \"%2\")")
+ .arg(_rx.mid(3, 2)).arg(command.mid(0, 2)));
+ return false;
+ }
+ // verify the checksum
+ uchar chk = 0;
+ for (uint i=1; i<size-3; i++) chk += _rx[i].latin1();
+ if ( chk!=fromHex(_rx.mid(size-3, 2), 0) ) {
+ log(Log::LineType::Error, i18n("Bad checksum for received string"));
+ return false;
+ }
+ return true;
+}
+
+bool Icd2::Hardware::command(const QString &command, uint responseSize)
+{
+ if ( hasError() ) return false;
+ if ( !sendCommand(command) ) return false;
+ if ( !receiveResponse(command, responseSize, false) ) return false;
+ return true;
+}
+
+bool Icd2::Hardware::getFirmwareVersion(VersionData &version)
+{
+ if ( !command("01", 6) ) return false;
+ version = VersionData::fromHexString(_rx.mid(5, 6));
+ return true;
+}
+
+uint Icd2::Hardware::getFirmwareId()
+{
+ if ( !command("07", 2) ) return 0;
+ return fromHex(_rx.mid(5, 2), 0);
+}
+
+bool Icd2::Hardware::getDebugExecVersion(VersionData &version)
+{
+ if ( !command("04", 6) ) return false;
+ version = VersionData::fromHexString(_rx.mid(5, 6));
+ return true;
+}
+
+bool Icd2::Hardware::setTargetPowerOn(bool on)
+{
+ return command(QString("05") + (on ? "FF" : "00"), 0);
+}
+
+bool Icd2::Hardware::readVoltage(Pic::VoltageType type, double &value)
+{
+ if ( !command(VOLTAGE_TYPE_DATA[type].command, 2) ) return false;
+ value = VOLTAGE_TYPE_DATA[type].factor * fromHex(_rx.mid(5, 2), 0);
+ return true;
+}
+
+bool Icd2::Hardware::readVoltages(VoltagesData &voltages)
+{
+ for (uint i=0; i<Pic::Nb_VoltageTypes; i++) {
+ if ( !readVoltage(Pic::VoltageType(i), voltages[i].value) ) return false;
+ voltages[i].error = false;
+ }
+ return true;
+}
+
+bool Icd2::Hardware::getTargetMode(Pic::TargetMode &tmode)
+{
+ if ( !command("2C", 2) ) return false;
+ uchar mode = fromHex(_rx.mid(5, 2), 0);
+ for (uint i=0; i<Pic::Nb_TargetModes; i++) {
+ if ( mode!=TARGET_MODE_VALUES[i] ) continue;
+ tmode = Pic::TargetMode(i);
+ return true;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+bool Icd2::Hardware::setTargetReset(Pic::ResetMode mode)
+{
+ return command(QString("33") + RESET_MODE_VALUES[mode], 0);
+}
+
+bool Icd2::Hardware::selfTest(TestData &test)
+{
+ if ( !command("02", 10) ) return false;
+ test = TestData(_rx);
+ return true;
+}
+
+bool Icd2::Hardware::readBlock(uint nbBytesWord, uint nbWords, Device::Array &data)
+{
+ //qDebug("readBlock %i %s", nbBytesWord, toHex(nbWords, 8).data());
+ // receive data
+ uint length = 2*nbBytesWord*nbWords+4;
+ QString s;
+ uint i = 0;
+ while ( i<length ) {
+ uint maxSize = (_port->type()==PortType::Serial ? 2*nbBytesWord : 0x100);
+ uint size = QMIN(maxSize, length-i);
+ QString tmp;
+ if ( _port->type()==PortType::USB ) {
+ if ( !static_cast<USBPort *>(_port)->dataReceive(size, tmp) ) return false;
+ } else if ( !_port->receive(size, tmp) ) return false;
+ s += tmp;
+ i += size;
+ }
+
+ // treat data
+ if ( s[0]!='{' || s[s.length()-1]!='}' ) {
+ log(Log::LineType::Error, i18n("Invalid begin or end character for read block."));
+ return false;
+ }
+ log(Log::DebugLevel::Max, "received: " + s);
+ data.resize(nbWords);
+ Q_UINT8 chk = 0;
+ for (uint i=0; i<nbWords; i++) {
+ QString ts = s.mid(1+2*nbBytesWord*i, 2*nbBytesWord);
+ //if ( i<10 ) qDebug("%i: %s", i, ts.data());
+ data[i] = 0;
+ for (int k=nbBytesWord-1; k>=0; k--) {
+ data[i] = data[i] << 8;
+ data[i] |= fromHex(ts.mid(2*k, 2), 0);
+ chk += ts[2*k].latin1() + ts[2*k+1].latin1();
+ }
+ }
+
+ QString cs = s.mid(s.length()-3, 2);
+ if ( chk!=fromHex(cs, 0) ) {
+ log(Log::LineType::Error, i18n("Bad checksum for read block: %1 (%2 expected).").arg(cs).arg(toHex(chk, 2)));
+ return false;
+ }
+ return true;
+}
+
+bool Icd2::Hardware::readMemory(Pic::MemoryRangeType type, uint wordOffset,
+ Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ const char *r = readCommand(type);
+ if ( r==0 ) return false;
+ uint nbBytesWord = device().nbBytesWord(type);
+ uint div = 2;
+ if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1;
+ uint inc = device().addressIncrement(type);
+ Address start = device().range(type).start; // address
+ uint todo = inc * data.count(); // address
+ uint offset = inc * wordOffset; // address
+ //qDebug("read size=%s div=%i nbBytes=%i", toHex(size, 8).data(), div, nbBytesWord);
+ data.resize(0);
+ do {
+ uint size = QMIN(todo, uint(0x1000)); // addresses
+ uint nb = size / inc; // word
+ //qDebug("read %s start=%s size=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data());
+ QString cmd = r + toHex(start+offset, 8) + toHex(nb/div, 8);
+ if ( !command(cmd, 0) ) return false;
+ Device::Array pdata;
+ if ( !readBlock(nbBytesWord, nb, pdata) ) return false;
+ if ( !receiveResponse(cmd, 0, false) ) return false;
+ if (vdata) {
+ for (uint i=0; i<pdata.count(); i++)
+ if ( !verifyWord(wordOffset+data.count()+i, pdata[i], type, *vdata) ) return false;
+ }
+ data += pdata;
+ offset += size;
+ todo -= size;
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom )
+ _base.progressMonitor().addTaskProgress(nb);
+ } while ( todo!=0 );
+ return true;
+}
+
+bool Icd2::Hardware::writeBlock(uint nbBytesWord, const Device::Array &data, uint wordIndex, uint nbWords)
+{
+ log(Log::DebugLevel::Extra, QString("writeBlock offset:%1 nbWords:%2 (size: %3)").arg(toHex(wordIndex, 8)).arg(toHex(nbWords, 8)).arg(toHex(data.size(), 8)));
+ Q_ASSERT( wordIndex+nbWords<=data.size() );
+ // prepare data
+ QString s = "{";
+ uchar chk = 0;
+ for (uint i=0; i<nbWords; i++) {
+ QString ts = toHex(data[wordIndex+i], 2*nbBytesWord);
+ for (int k=nbBytesWord-1; k>=0; k--) {
+ //if ( i<10 || i>=nbWords-10 ) qDebug("send: %i-%i %s", i, k, ts.mid(2*k, 2).data());
+ s += ts.mid(2*k, 2);
+ chk += ts[2*k].latin1() + ts[2*k+1].latin1();
+ }
+ }
+ s += toHex(chk, 2);
+ s += "}";
+ log(Log::DebugLevel::Max, "send: " + s);
+
+ // send data
+ uint i = 0;
+ while ( i<uint(s.length()) ) {
+ uint maxSize = (_port->description().type==PortType::Serial ? 2*nbBytesWord : 0x100);
+ if ( _port->description().type==PortType::Serial && i==0 ) maxSize = 1;
+ uint size = QMIN(maxSize, s.length()-i);
+ QByteArray a = toAscii(s);
+ if ( _port->type()==PortType::USB ) {
+ if ( !static_cast<USBPort *>(_port)->dataSend(a.data()+i, size) ) return false;
+ } else if ( !_port->send(a.data()+i, size) ) return false;
+ i += size;
+ }
+
+ //qDebug("done sending %i words (chk=%s)", nbWords, toHex(chk, 2).data());
+ return true;
+}
+
+bool Icd2::Hardware::writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data)
+{
+ //qDebug("write memory: offset:%s nbWords:%s (size: %s)", toHex(wordOffset, 4).data(), toHex(nbWords, 4).data(), toHex(data.size(), 4).data());
+ const char *w = writeCommand(type);
+ if ( w==0 ) return true;
+ uint nbBytesWord = device().nbBytesWord(type);
+ uint div = 2;
+ if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1;
+ uint inc = device().addressIncrement(type);
+ Address start = device().range(type).start; // address
+ uint todo = inc * data.count(); // address
+ uint offset = inc * wordOffset; // address
+ uint index = 0;
+ //qDebug("write todo=%s div=%i nbBytes=%i dataSize=%i", toHex(todo, 8).data(), div, nbBytesWord, data.size());
+ do {
+ uint size = QMIN(todo, uint(0x1000)); // address
+ uint nb = size / inc; // word
+ //qDebug("write %s start=%s nbWords=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data());
+ QString cmd = w + toHex(start+offset+index, 8) + toHex(nb/div, 8);
+ if ( !command(cmd, 0) ) return false;
+ if ( !writeBlock(nbBytesWord, data, index/inc, nb) ) return false;
+ if ( !receiveResponse(cmd, 0, false) ) return false;
+ index += size;
+ todo -= size;
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom )
+ _base.progressMonitor().addTaskProgress(nb);
+ } while ( todo!=0 );
+ return true;
+}
+
+bool Icd2::Hardware::eraseAll()
+{
+ setTargetReset(Pic::ResetHeld);
+ if ( hasError() ) return false;
+ if ( !sendCommand("29") ) return false;
+ if ( !receiveResponse("29", 0, true) ) return false; // poll
+ return true;
+}
+
+bool Icd2::Hardware::haltRun()
+{
+ return command("2E", 0);
+}
+
+bool Icd2::Hardware::step()
+{
+ return command("2F", 0);
+}
+
+bool Icd2::Hardware::resumeRun()
+{
+ return command("30", 0);
+}
+
+bool Icd2::Hardware::setWriteMode(Pic::WriteMode mode)
+{
+ return command(QString("4B") + WRITE_MODE_VALUES[mode], 0);
+}
+
+bool Icd2::Hardware::writeRegister(Address address, BitValue value, uint nbBytes)
+{
+ QString cmd = "1B" + toHex(address, 8) + toHex(nbBytes, 8);
+ if ( !command(cmd, 0) ) return false;
+ Device::Array data(nbBytes);
+ for (uint i=0; i<nbBytes; i++) data[nbBytes-i-1] = value.byte(i);
+ if ( !writeBlock(1, data, 0, nbBytes) ) return false;
+ return receiveResponse(cmd, 0, false);
+}
+
+bool Icd2::Hardware::readRegister(Address address, BitValue &value, uint nbBytes)
+{
+ QString cmd = "1E" + toHex(address, 8) + toHex(nbBytes, 8);
+ if ( !command(cmd, 0) ) return false;
+ Device::Array data;
+ if ( !readBlock(1, nbBytes, data) ) return false;
+ if ( !receiveResponse(cmd, 0, false) ) return false;
+ value = 0;
+ for (uint i=0; i<nbBytes; i++) {
+ value <<= 8;
+ value += data[i];
+ }
+ return true;
+}
+
+BitValue Icd2::Hardware::getProgramCounter()
+{
+ if ( !command("3D", 8) ) return 0;
+ return fromHex(_rx.mid(5, 8), 0);
+}
diff --git a/src/progs/icd2/base/icd2.h b/src/progs/icd2/base/icd2.h
new file mode 100644
index 0000000..1c9c1b9
--- /dev/null
+++ b/src/progs/icd2/base/icd2.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_H
+#define ICD2_H
+
+#include "icd.h"
+
+namespace Icd2
+{
+//-----------------------------------------------------------------------------
+ extern const uchar TARGET_MODE_VALUES[Pic::Nb_TargetModes];
+ extern const char * const RESET_MODE_VALUES[Pic::Nb_ResetModes];
+
+ class TestData {
+ public:
+ TestData();
+ TestData(const QString &rx);
+ enum VoltageType { TargetVdd = 0, ModuleVpp, MclrGround, MclrVdd, MclrVpp,
+ Nb_VoltageTypes };
+ bool pass() const;
+ QString result(VoltageType type) const;
+ QString pretty(VoltageType type) const;
+ static const char * const VOLTAGE_LABELS[Nb_VoltageTypes];
+
+ private:
+ int _voltages[Nb_VoltageTypes];
+ static const int RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1];
+ };
+
+//-----------------------------------------------------------------------------
+class Hardware : public Icd::Hardware
+{
+public:
+ Hardware(::Programmer::Base &base, Port::Base *port) : Icd::Hardware(base, port) {}
+ bool command(const QString &command, uint responseSize);
+
+// initialization
+ virtual bool uploadFirmware(const Pic::Memory &memory);
+ virtual bool setTarget();
+ bool setup();
+
+// status
+ virtual bool getFirmwareVersion(VersionData &version);
+ uint getFirmwareId();
+ bool getDebugExecVersion(VersionData &version);
+ virtual bool setTargetPowerOn(bool on);
+ virtual bool readVoltage(Pic::VoltageType type, double &value);
+ virtual bool readVoltages(VoltagesData &voltages);
+ virtual bool getTargetMode(Pic::TargetMode &mode);
+ virtual bool setTargetReset(Pic::ResetMode mode);
+ bool selfTest(TestData &test);
+
+// programming
+ virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata);
+ virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data);
+ virtual bool eraseAll();
+ bool setWriteMode(Pic::WriteMode mode);
+
+// debugging
+ virtual bool readRegister(Address address, BitValue &value, uint nbBytes);
+ virtual bool writeRegister(Address address, BitValue value, uint nbBytes);
+ virtual bool resumeRun();
+ virtual bool step();
+ virtual bool haltRun();
+ virtual BitValue getProgramCounter();
+
+protected:
+ virtual QString receivedData() const { return _rx.mid(5, _rx.length()-8); }
+
+private:
+ struct VoltageTypeData {
+ const char *command;
+ double factor;
+ };
+ static const VoltageTypeData VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes];
+ static const char * const WRITE_MODE_VALUES[Pic::Nb_WriteModes];
+
+ bool sendCommand(const QString &command);
+ bool receiveResponse(const QString &command, uint responseSize, bool poll);
+ bool readBlock(uint nbBytesWord, uint nbWords, Device::Array &data);
+ bool writeBlock(uint nbBytesWord, const Device::Array &data, uint wordOffset, uint nbWords);
+ const char *readCommand(Pic::MemoryRangeType type) const;
+ const char *writeCommand(Pic::MemoryRangeType type) const;
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2.xml b/src/progs/icd2/base/icd2.xml
new file mode 100644
index 0000000..3c714b2
--- /dev/null
+++ b/src/progs/icd2/base/icd2.xml
@@ -0,0 +1,214 @@
+<!-- ************************************************************************* -->
+<!-- * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * -->
+<!-- * * -->
+<!-- * it under the terms of the GNU General Public License as published by * -->
+<!-- * This program is free software; you can redistribute it and/or modify * -->
+<!-- * the Free Software Foundation; either version 2 of the License, or * -->
+<!-- * (at your option) any later version. * -->
+<!-- *************************************************************************/-->
+<!DOCTYPE piklab>
+
+<type name="icd2">
+ <device name="10F200" famid="0x12" family="10F2XX" support_type="tested" />
+ <device name="10F202" famid="0x12" family="10F2XX" support_type="tested" />
+ <device name="10F204" famid="0x12" family="10F2XX" support_type="tested" />
+ <device name="10F206" famid="0x12" family="10F2XX" support_type="tested" />
+ <device name="10F220" famid="0x12" family="10F2XX" />
+ <device name="10F222" famid="0x12" family="10F2XX" />
+
+ <device name="12F508" famid="0x11" family="16F5X" support_type="tested" />
+ <device name="12F509" famid="0x11" family="16F5X" support_type="tested" />
+ <device name="12F510" famid="0x11" family="16F5X" support_type="tested" />
+ <device name="12F629" famid="0x05" family="12F629" support_type="tested" />
+ <device name="12F635" famid="0x0C" family="12F635" support_type="tested" />
+ <device name="12F675" famid="0x05" family="12F629" support_type="tested" />
+ <device name="12F683" famid="0x0C" family="12F635" support_type="tested" />
+
+ <device name="16F505" famid="0x10" family="16F5X" />
+ <device name="16F506" famid="0x12" family="16F5X" />
+ <device name="16F54" famid="0x0E" family="16F5X" support_type="tested" />
+ <device name="16F57" famid="0x0F" family="16F5X" support_type="tested" />
+ <device name="16F59" famid="0x0F" family="16F5X" support_type="tested" />
+ <device name="16F616" famid="0x1A" family="16F61X" />
+ <device name="16F627" famid="0x19" family="16F72" />
+ <device name="16F628" famid="0x19" family="16F72" />
+ <device name="16F627A" famid="0x09" family="16F648A" support_type="tested" />
+ <device name="16F628A" famid="0x09" family="16F648A" support_type="tested" />
+ <device name="16F630" famid="0x05" family="16F676" />
+ <device name="16F631" famid="0x0C" family="12F635" />
+ <device name="16F636" famid="0x0C" family="12F635" />
+ <device name="16F639" famid="0x0C" family="12F635" />
+ <device name="16F648A" famid="0x09" family="16F648A" support_type="tested" />
+ <device name="16F676" famid="0x05" family="16F676" />
+ <device name="16F677" famid="0x0C" family="16F677" />
+ <device name="16F684" famid="0x0C" family="16F684" support_type="tested" />
+ <device name="16F685" famid="0x0C" family="16F688" support_type="tested" />
+ <device name="16F687" famid="0x0C" family="16F688" support_type="tested" />
+ <device name="16F688" famid="0x0C" family="16F688" support_type="tested" />
+ <device name="16F689" famid="0x0C" family="16F688" support_type="tested" />
+ <device name="16F690" famid="0x0C" family="16F688" support_type="tested" />
+ <device name="16F716" famid="0x0B" family="16F716" />
+ <device name="16F72" famid="0x21" family="16F72" />
+ <device name="16F73" famid="0x0A" family="16F7X" />
+ <device name="16F74" famid="0x0A" family="16F7X" />
+ <device name="16F76" famid="0x0A" family="16F7X" />
+ <device name="16F77" famid="0x0A" family="16F7X" />
+ <device name="16F737" famid="0x0A" family="16F7X7" support_type="tested" />
+ <device name="16F747" famid="0x0A" family="16F7X7" support_type="tested" />
+ <device name="16F767" famid="0x0A" family="16F7X7" support_type="tested" />
+ <device name="16F777" famid="0x0A" family="16F7X7" support_type="tested" />
+ <device name="16F785" famid="0x15" family="16F785" />
+ <device name="16F818" famid="0x06" family="16F819" support_type="tested" />
+ <device name="16F819" famid="0x06" family="16F819" support_type="tested" />
+ <device name="16F84A" famid="0x20" family="16F72" />
+ <device name="16F87" famid="0x08" family="16F88" support_type="tested" />
+ <device name="16F870" famid="0x03" family="16F872" />
+ <device name="16F871" famid="0x03" family="16F872" support_type="tested" debug_support_type="tested" />
+ <device name="16F872" famid="0x03" family="16F872" support_type="tested" />
+ <device name="16F873" famid="0x03" family="16F874" support_type="tested" />
+ <device name="16F873A" famid="0x04" family="16F874" />
+ <device name="16F874" famid="0x03" family="16F874" support_type="tested" />
+ <device name="16F874A" famid="0x04" family="16F874" />
+ <device name="16F876" famid="0x03" family="16F877" support_type="tested" />
+ <device name="16F876A" famid="0x04" family="16F877" />
+ <device name="16F877" famid="0x03" family="16F877" support_type="tested" debug_support_type="tested" />
+ <device name="16F877A" famid="0x04" family="16F877" />
+ <device name="16F88" famid="0x08" family="16F88" support_type="tested" />
+ <device name="16F913" famid="0x14" family="16F916" />
+ <device name="16F914" famid="0x14" family="16F916" />
+ <device name="16F916" famid="0x14" family="16F916" />
+ <device name="16F917" famid="0x14" family="16F916" />
+ <device name="16F946" famid="0x14" family="16F916" />
+
+ <device name="18C601" famid="0x81" family="18CX01" />
+ <device name="18C801" famid="0x81" family="18CX01" />
+
+ <device name="18F242" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F248" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F252" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F258" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F442" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F448" famid="0x82" family="18F_4" support_type="tested" />
+ <device name="18F452" famid="0x82" family="18F_4" support_type="tested" debug_support_type="tested" />
+ <device name="18F458" famid="0x82" family="18F_4" support_type="tested" debug_support_type="tested" />
+
+ <device name="18F1220" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F1230" famid="0x8F" family="18F_5" />
+ <device name="18F1320" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F1330" famid="0x8F" family="18F_5" />
+ <device name="18F2220" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F2221" famid="0x8C" family="18F_5" />
+ <device name="18F2320" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F2321" famid="0x8C" family="18F_5" />
+ <device name="18F2331" famid="0x87" family="18F_4" />
+ <device name="18F2410" famid="0x8C" family="18F_5" />
+ <device name="18F2420" famid="0x8C" family="18F_5" />
+ <device name="18F2423" famid="0x8B" family="18F_5" />
+ <device name="18F2431" famid="0x87" family="18F_4" />
+ <device name="18F2439" famid="0x85" family="18F_4" />
+ <device name="18F2450" famid="0x8C" family="18F_5" />
+ <device name="18F2455" famid="0x8B" family="18F_5" />
+ <device name="18F2480" famid="0x8C" family="18F_5" support_type="tested" />
+ <device name="18F2510" famid="0x88" family="18F_5" support_type="tested" />
+ <device name="18F2515" famid="0x88" family="18F_5" />
+ <device name="18F2520" famid="0x8C" family="18F_5" />
+ <device name="18F2523" famid="0x8B" family="18F_5" />
+ <device name="18F2525" famid="0x88" family="18F_5" />
+ <device name="18F2539" famid="0x85" family="18F_4" />
+ <device name="18F2550" famid="0x8B" family="18F_5" />
+ <device name="18F2580" famid="0x8C" family="18F_5" support_type="tested" />
+ <device name="18F2585" famid="0x88" family="18F_5" />
+ <device name="18F2610" famid="0x88" family="18F_5" />
+ <device name="18F2620" famid="0x88" family="18F_5" />
+ <device name="18F2680" famid="0x88" family="18F_5" />
+ <device name="18F2682" famid="0x90" family="18F_5" />
+ <device name="18F2685" famid="0x90" family="18F_5" />
+
+ <device name="18F4220" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F4221" famid="0x8C" family="18F_5" />
+ <device name="18F4320" famid="0x83" family="18F_4" support_type="tested" />
+ <device name="18F4321" famid="0x8C" family="18F_5" />
+ <device name="18F4331" famid="0x87" family="18F_4" />
+ <device name="18F4410" famid="0x8C" family="18F_5" />
+ <device name="18F4420" famid="0x8C" family="18F_5" />
+ <device name="18F4423" famid="0x8B" family="18F_5" />
+ <device name="18F4431" famid="0x87" family="18F_4" />
+ <device name="18F4439" famid="0x85" family="18F_4" />
+ <device name="18F4450" famid="0x8C" family="18F_5" />
+ <device name="18F4455" famid="0x8B" family="18F_5" />
+ <device name="18F4480" famid="0x8C" family="18F_5" support_type="tested" />
+ <device name="18F4510" famid="0x88" family="18F_5" support_type="tested" />
+ <device name="18F4515" famid="0x88" family="18F_5" />
+ <device name="18F4520" famid="0x8C" family="18F_5" />
+ <device name="18F4523" famid="0x8B" family="18F_5" />
+ <device name="18F4525" famid="0x88" family="18F_5" />
+ <device name="18F4539" famid="0x85" family="18F_4" />
+ <device name="18F4550" famid="0x8B" family="18F_5" />
+ <device name="18F4580" famid="0x8C" family="18F_5" support_type="tested" />
+ <device name="18F4585" famid="0x88" family="18F_5" />
+ <device name="18F4610" famid="0x88" family="18F_5" />
+ <device name="18F4620" famid="0x88" family="18F_5" />
+ <device name="18F4680" famid="0x88" family="18F_5" />
+ <device name="18F4682" famid="0x90" family="18F_5" />
+ <device name="18F4685" famid="0x90" family="18F_5" />
+
+ <device name="18F6310" famid="0x8A" family="18F_4" />
+ <device name="18F6390" famid="0x8A" family="18F_4" />
+ <device name="18F6410" famid="0x8A" family="18F_5" />
+ <device name="18F6490" famid="0x8A" family="18F_5" />
+ <device name="18F6520" famid="0x84" family="18F_4" />
+ <device name="18F6525" famid="0x86" family="18F_4" />
+ <device name="18F6527" famid="0x8D" family="18F_5" />
+ <device name="18F6585" famid="0x86" family="18F_4" />
+ <device name="18F6620" famid="0x84" family="18F_4" />
+ <device name="18F6621" famid="0x86" family="18F_4" />
+ <device name="18F6622" famid="0x8D" family="18F_5" />
+ <device name="18F6627" famid="0x8D" family="18F_5" />
+ <device name="18F6680" famid="0x86" family="18F_4" />
+ <device name="18F6720" famid="0x84" family="18F_4" />
+ <device name="18F6722" famid="0x8D" family="18F_5" />
+
+ <device name="18F8310" famid="0x8A" family="18F_4" />
+ <device name="18F8390" famid="0x8A" family="18F_4" />
+ <device name="18F8410" famid="0x8A" family="18F_5" />
+ <device name="18F8490" famid="0x8A" family="18F_5" />
+ <device name="18F8520" famid="0x84" family="18F_4" />
+ <device name="18F8525" famid="0x86" family="18F_4" />
+ <device name="18F8527" famid="0x8D" family="18F_5" />
+ <device name="18F8585" famid="0x86" family="18F_4" />
+ <device name="18F8620" famid="0x84" family="18F_4" />
+ <device name="18F8621" famid="0x86" family="18F_4" />
+ <device name="18F8622" famid="0x8D" family="18F_5" />
+ <device name="18F8627" famid="0x8D" family="18F_5" />
+ <device name="18F8680" famid="0x86" family="18F_4" />
+ <device name="18F8720" famid="0x84" family="18F_4" />
+ <device name="18F8722" famid="0x8D" family="18F_5" />
+
+ <device name="18F24J10" famid="0x40" family="18F_J" />
+ <device name="18F66J60" famid="0x40" family="18F_J" support_type="tested" />
+
+ <device name="30F2010" famid="0xBB" family="30F" />
+ <device name="30F2011" famid="0xBB" family="30F" />
+ <device name="30F2012" famid="0xBB" family="30F" />
+ <device name="30F3010" famid="0xBB" family="30F" />
+ <device name="30F3011" famid="0xBB" family="30F" />
+ <device name="30F3012" famid="0xBB" family="30F" />
+ <device name="30F3013" famid="0xBB" family="30F" />
+ <device name="30F3014" famid="0xBB" family="30F" />
+ <device name="30F4011" famid="0xBB" family="30F" />
+ <device name="30F4012" famid="0xBB" family="30F" />
+ <device name="30F4013" famid="0xBB" family="30F" />
+ <device name="30F5011" famid="0xBB" family="30F" />
+ <device name="30F5013" famid="0xBB" family="30F" />
+ <device name="30F6010" famid="0xBB" family="30F" />
+ <device name="30F6011" famid="0xBB" family="30F" />
+ <device name="30F6012" famid="0xBB" family="30F" />
+ <device name="30F6013" famid="0xBB" family="30F" />
+ <device name="30F6014" famid="0xBB" family="30F" />
+ <device name="30F6015" famid="0xBB" family="30F" />
+ <device name="30F6010A" famid="0xBB" family="30F" />
+ <device name="30F6011A" famid="0xBB" family="30F" />
+ <device name="30F6012A" famid="0xBB" family="30F" />
+ <device name="30F6013A" famid="0xBB" family="30F" />
+ <device name="30F6014A" famid="0xBB" family="30F" />
+</type> \ No newline at end of file
diff --git a/src/progs/icd2/base/icd2_data.h b/src/progs/icd2/base/icd2_data.h
new file mode 100644
index 0000000..ceda394
--- /dev/null
+++ b/src/progs/icd2/base/icd2_data.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_DATA_H
+#define ICD2_DATA_H
+
+#include "common/common/group.h"
+
+namespace Icd2
+{
+ struct Version {
+ uchar major, minor, dot;
+ };
+ enum { Nb_Firmwares = 15 };
+ struct FirmwareVersionData {
+ uchar mplabMajor, mplabMinor;
+ Version version[Nb_Firmwares];
+ };
+ extern const FirmwareVersionData MIN_VERSION_DATA;
+ extern const FirmwareVersionData MAX_VERSION_DATA;
+ struct FamilyData {
+ const char *name;
+ uchar efid;
+ const char *debugExec;
+ uint debugExecOffset; // in the hex file
+ uint wreg, fsr, status;
+ };
+ extern const FamilyData FAMILY_DATA[];
+ struct Data {
+ uint famid;
+ ::Group::Support debugSupport;
+ };
+ extern const Data &data(const QString &device);
+ extern uint family(const QString &device);
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_debug.cpp b/src/progs/icd2/base/icd2_debug.cpp
new file mode 100644
index 0000000..62f6404
--- /dev/null
+++ b/src/progs/icd2/base/icd2_debug.cpp
@@ -0,0 +1,348 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_debug.h"
+
+#include "common/global/pfile.h"
+#include "progs/base/prog_config.h"
+#include "devices/pic/base/pic_register.h"
+#include "devices/pic/pic/pic_group.h"
+#include "icd2_data.h"
+#include "icd2_debug_specific.h"
+
+//-----------------------------------------------------------------------------
+Icd2::DebuggerSpecific *Icd2::Debugger::specific() { return static_cast<Icd2::DebuggerSpecific *>(_specific); }
+
+bool Icd2::Debugger::waitForTargetMode(Pic::TargetMode mode)
+{
+ Pic::TargetMode rmode;
+ for (uint i=0; i<20; i++) {
+ if ( !programmer().getTargetMode(rmode) ) return false;
+ if ( rmode==mode ) return true;
+ Port::msleep(200);
+ }
+ log(Log::LineType::Error, QString("Timeout waiting for mode: %1 (target is in mode: %2).")
+ .arg(i18n(Pic::TARGET_MODE_LABELS[mode])).arg(i18n(Pic::TARGET_MODE_LABELS[rmode])));
+ return false;
+}
+
+bool Icd2::Debugger::init(bool last)
+{
+ _initLast = last;
+ return ::Debugger::PicBase::init();
+}
+
+bool Icd2::Debugger::internalInit()
+{
+ return specific()->init(_initLast);
+}
+
+bool Icd2::Debugger::updateState()
+{
+ Pic::TargetMode mode;
+ if ( !programmer().getTargetMode(mode) ) return false;
+ switch (mode) {
+ case Pic::TargetStopped: _programmer.setState(::Programmer::Halted); break;
+ case Pic::TargetRunning: _programmer.setState(::Programmer::Running); break;
+ case Pic::TargetInProgramming: _programmer.setState(::Programmer::Stopped); break;
+ case Pic::Nb_TargetModes: Q_ASSERT(false); break;
+ }
+ return true;
+}
+
+bool Icd2::Debugger::setBreakpoints(const QValueList<Address> &addresses)
+{
+ if ( addresses.count()==0 ) return specific()->setBreakpoint(Address());
+ for (uint i=0; i<uint(addresses.count()); i++) {
+ log(Log::DebugLevel::Normal, QString("Set breakpoint at %1").arg(toHexLabel(addresses[i], device()->nbCharsAddress())));
+ if ( !specific()->setBreakpoint(addresses[i]) ) return false;
+ }
+ return true;
+}
+
+bool Icd2::Debugger::internalRun()
+{
+ return hardware()->resumeRun();
+}
+
+bool Icd2::Debugger::hardHalt()
+{
+ log(Log::LineType::Warning, i18n("Failed to halt target: try a reset."));
+ return reset();
+}
+
+bool Icd2::Debugger::softHalt(bool &success)
+{
+ if ( !hardware()->haltRun() ) return false;
+ success = waitForTargetMode(Pic::TargetStopped);
+ return true;
+}
+
+bool Icd2::Debugger::internalReset()
+{
+ return specific()->reset();
+}
+
+bool Icd2::Debugger::internalStep()
+{
+ return hardware()->step();
+}
+
+bool Icd2::Debugger::readRegister(const Register::TypeData &data, BitValue &value)
+{
+ if ( data.type()==Register::Special ) {
+ if ( data.name()=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1);
+ if ( data.name()=="PC" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()); return !hasError(); }
+ Q_ASSERT(false);
+ return true;
+ }
+ QString name = device()->registersData().sfrNames[data.address()];
+ if ( name=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1);
+ if ( name=="PCL" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(0); return !hasError(); }
+ if ( name=="PCLATH" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(1); return !hasError(); }
+ return hardware()->readRegister(specific()->addressRegister(data.address()), value, 1);
+}
+
+bool Icd2::Debugger::writeRegister(const Register::TypeData &data, BitValue value)
+{
+ if ( data.type()==Register::Special ) {
+ if ( data.name()=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1);
+ Q_ASSERT(false);
+ return true;
+ }
+ QString name = device()->registersData().sfrNames[data.address()];
+ if ( name=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1);
+ return hardware()->writeRegister(specific()->addressRegister(data.address()), value, 1);
+}
+
+//-----------------------------------------------------------------------------
+Icd2::DebugProgrammer::DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data)
+ : Icd2::ProgrammerBase(group, data, "icd2_programmer")
+{}
+
+void Icd2::DebugProgrammer::clear()
+{
+ Icd2::ProgrammerBase::clear();
+ _debugExecutiveVersion.clear();
+}
+
+bool Icd2::DebugProgrammer::internalSetupHardware()
+{
+ if ( _specific==0 ) return true;
+ const FamilyData &fdata = FAMILY_DATA[family(device()->name())];
+
+ // find debug executive file
+ PURL::Directory dir(::Programmer::GroupConfig::firmwareDirectory(group()));
+ if ( !dir.exists() ) {
+ log(Log::LineType::Error, i18n("Firmware directory not configured."));
+ return false;
+ }
+ uint reservedBank = 0;
+ QString filename;
+ if ( device()->is18Family() ) {
+ Debugger *debug = static_cast<Debugger *>(debugger());
+ reservedBank = static_cast<const P18FDebuggerSpecific *>(debug->specific())->reservedBank();
+ filename = QString("de18F_BANK%1.hex").arg(QString(toString(NumberBase::Dec, reservedBank, 2)));
+ } else filename = QString("de%1.hex").arg(fdata.debugExec);
+ PURL::Url url = dir.findMatchingFilename(filename);
+ log(Log::DebugLevel::Normal, QString(" Debug executive file: %1").arg(url.pretty()));
+ if ( !url.exists() ) {
+ log(Log::LineType::Error, i18n("Could not find debug executive file \"%1\".").arg(url.pretty()));
+ return false;
+ }
+ // upload hex file
+ Log::StringView sview;
+ PURL::File file(url, sview);
+ if ( !file.openForRead() ) {
+ log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty()));
+ return false;
+ }
+ QStringList errors;
+ HexBuffer hbuffer;
+ if ( !hbuffer.load(file.stream(), errors) ) {
+ log(Log::LineType::Error, i18n("Could not read debug executive file \"%1\": %2.").arg(url.pretty()).arg(errors[0]));
+ return false;
+ }
+ uint nbWords = device()->nbWords(Pic::MemoryRangeType::Code);
+ uint offset = nbWords - 0x100;
+ if ( fdata.debugExecOffset!=0 && fdata.debugExecOffset!=offset )
+ for (uint i=0; i<0x100; i++) hbuffer.insert(offset+i, hbuffer[fdata.debugExecOffset+i]);
+ Pic::Memory::WarningTypes warningTypes;
+ QStringList warnings;
+ QMap<uint, bool> inRange;
+ Pic::Memory memory(*device());
+ memory.fromHexBuffer(Pic::MemoryRangeType::Code, hbuffer, warningTypes, warnings, inRange);
+ _deArray = memory.arrayForWriting(Pic::MemoryRangeType::Code);
+ if ( device()->is18Family() ) {
+ // that's a bit ugly but it cannot be guessed for 18F2455 family...
+ uint size;
+ switch (reservedBank) {
+ case 0: size = 0x0E0; break;
+ case 12:
+ case 14: size = 0x140; break;
+ default: size = 0x120; break;
+ }
+ _deStart = nbWords - size;
+ _deEnd = nbWords - 1;
+ for (uint i=0; i<size; i++) {
+ BitValue v = memory.word(Pic::MemoryRangeType::Code, i);
+ memory.setWord(Pic::MemoryRangeType::Code, i, BitValue());
+ memory.setWord(Pic::MemoryRangeType::Code, _deStart+i, v);
+ }
+ _deArray = memory.arrayForWriting(Pic::MemoryRangeType::Code);
+ } else {
+ _deStart = specific()->findNonMaskStart(Pic::MemoryRangeType::Code, _deArray);
+ _deEnd = specific()->findNonMaskEnd(Pic::MemoryRangeType::Code, _deArray);
+ }
+ log(Log::DebugLevel::Extra, QString("debug executive: \"%1\" %2:%3").arg(url.pretty()).arg(toHexLabel(_deStart, 4)).arg(toHexLabel(_deEnd, 4)));
+ return Icd2::ProgrammerBase::internalSetupHardware();
+}
+
+Pic::Memory Icd2::DebugProgrammer::toDebugMemory(const Pic::Memory &mem, bool withDebugExecutive)
+{
+ Pic::Memory memory = mem;
+ memory.setDebugOn(true);
+ if ( memory.hasWatchdogTimerOn() ) {
+ log(Log::LineType::Warning, i18n("Disabling watchdog timer for debugging"));
+ memory.setWatchdogTimerOn(false);
+ }
+ if ( memory.isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code) ) {
+ log(Log::LineType::Warning, i18n("Disabling code program protection for debugging"));
+ memory.setProtection(false, Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code);
+ }
+ if ( memory.isProtected(Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code) ) {
+ log(Log::LineType::Warning, i18n("Disabling code write protection for debugging"));
+ memory.setProtection(false, Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code);
+ }
+ if ( memory.isProtected(Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code) ) {
+ log(Log::LineType::Warning, i18n("Disabling code read protection for debugging"));
+ memory.setProtection(false, Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code);
+ }
+ uint address = _deStart * device()->addressIncrement(Pic::MemoryRangeType::Code);
+ Device::Array data = device()->gotoInstruction(address, false);
+ for (uint i=0; i<data.count(); i++) memory.setWord(Pic::MemoryRangeType::DebugVector, i, data[i]);
+ if ( device()->is18Family() )
+ memory.setWord(Pic::MemoryRangeType::DebugVector, data.count(), 0xFF00); // ??
+ if (withDebugExecutive) {
+ bool ok = true;
+ for (uint i=_deStart; i<=_deEnd; i++) {
+ if ( memory.word(Pic::MemoryRangeType::Code, i).isInitialized() ) ok = false;
+ memory.setWord(Pic::MemoryRangeType::Code, i, _deArray[i]);
+ }
+ if ( !ok ) log(Log::LineType::Warning, i18n("Memory area for debug executive was not empty. Overwrite it and continue anyway..."));
+ }
+ return memory;
+}
+
+bool Icd2::DebugProgrammer::writeDebugExecutive()
+{
+ log(Log::LineType::Information, i18n(" Write debug executive"));
+ Device::Array data = _deArray.mid(_deStart, _deEnd - _deStart + 1);
+ if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, _deStart, data) ) return false;
+ log(Log::LineType::Information, i18n(" Verify debug executive"));
+ if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, _deStart, data, 0) ) return false;
+ for (uint i=0; i<data.count(); i++) {
+ if ( _deArray[_deStart+i]==data[i] ) continue;
+ uint inc = device()->addressIncrement(Pic::MemoryRangeType::Code);
+ Address address = device()->range(Pic::MemoryRangeType::Code).start + inc * (_deStart + i);
+ log(Log::LineType::Error, i18n("Device memory doesn't match debug executive (at address %1: reading %2 and expecting %3).")
+ .arg(toHexLabel(address, device()->nbCharsAddress()))
+ .arg(toHexLabel(data[i], device()->nbCharsWord(Pic::MemoryRangeType::Code)))
+ .arg(toHexLabel(_deArray[_deStart+i], device()->nbCharsWord(Pic::MemoryRangeType::Code))));
+ return false;
+ }
+ return true;
+}
+
+bool Icd2::DebugProgrammer::doProgram(const Device::Memory &memory, const Device::MemoryRange &range)
+{
+ if ( !checkProgram(memory) ) return false;
+ if ( !doConnectDevice() ) return false;
+ _progressMonitor.startNextTask();
+ // probably needed for all devices that don't have a "erase and write" mode
+ if ( range.all() && FAMILY_DATA[family(device()->name())].debugExec==QString("16F7X7") ) {
+ Pic::Memory dmemory(*device());
+ dmemory.setWord(Pic::MemoryRangeType::Code, 0, 0x0028);
+ dmemory.setWord(Pic::MemoryRangeType::Code, 1, 0x0030);
+ log(Log::LineType::Information, i18n("Programming device for debugging test..."));
+ if ( !internalProgram(dmemory, range) ) return false;
+ if ( !static_cast<Debugger *>(_debugger)->init(false) ) return false;
+ log(Log::LineType::Information, i18n("Debugging test successful"));
+ }
+ log(Log::LineType::Information, i18n("Programming device memory..."));
+ if ( !internalProgram(memory, range) ) return false;
+ log(Log::LineType::Information, i18n("Programming successful"));
+ return static_cast<Debugger *>(_debugger)->init(true);
+}
+
+bool Icd2::DebugProgrammer::programAll(const Pic::Memory &mem)
+{
+ Pic::Memory memory = toDebugMemory(mem, false);
+ if ( !programAndVerifyRange(Pic::MemoryRangeType::Code, memory) ) return false;
+ if ( !writeDebugExecutive() ) return false;
+ if ( !programAndVerifyRange(Pic::MemoryRangeType::DebugVector, memory) ) return false;
+ if ( !programAndVerifyRange(Pic::MemoryRangeType::Eeprom, memory) ) return false;
+ if ( !programAndVerifyRange(Pic::MemoryRangeType::UserId, memory) ) return false;
+ if ( device()->is18Family() ) {
+ if ( !hardware()->command("0C00", 0) ) return false; // #### ??
+ QString com = "42" + toHex(0xFB5, 8) + toHex(1, 8); // write RSBUG (?)
+ if ( !hardware()->command(com, 0) ) return false;
+ if ( !hardware()->command("0C01", 0) ) return false; // #### ??
+ }
+ if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, memory) ) return false;
+ return true;
+}
+
+bool Icd2::DebugProgrammer::internalRead(Device::Memory *mem, const Device::MemoryRange &range, const ::Programmer::VerifyData *vd)
+{
+ if ( vd==0 || (vd->actions & ::Programmer::BlankCheckVerify) ) return Icd2::ProgrammerBase::internalRead(mem, range, vd);
+ Pic::Memory memory = toDebugMemory(static_cast<const Pic::Memory &>(vd->memory), true);
+ ::Programmer::VerifyData vdata(vd->actions, memory);
+ if ( !Icd2::ProgrammerBase::internalRead(0, range, &vdata) ) return false;
+ if ( range.all() && !readRange(Pic::MemoryRangeType::DebugVector, 0, &vdata) ) return false;
+ return true;
+}
+
+bool Icd2::DebugProgrammer::readDebugExecutiveVersion()
+{
+ if ( !hardware()->getDebugExecVersion(_debugExecutiveVersion) ) return false;
+ log(Log::LineType::Information, i18n(" Debug executive version: %1").arg(_debugExecutiveVersion.pretty()));
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void Icd2::DebuggerGroup::addDevice(const QString &name, const Device::Data *ddata, ::Group::Support)
+{
+ if ( FAMILY_DATA[family(name)].debugExec==0 ) return;
+ Group::addDevice(name, ddata, data(name).debugSupport);
+}
+
+::Debugger::Specific *Icd2::DebuggerGroup::createDebuggerSpecific(::Debugger::Base &base) const
+{
+ const Pic::Data *data = static_cast< ::Debugger::PicBase &>(base).device();
+ if ( data==0 ) return 0;
+ QString debugExec = FAMILY_DATA[family(data->name())].debugExec;
+ switch (data->architecture().type()) {
+ case Pic::Architecture::P16X:
+ if ( debugExec=="16F872" ) return new P16F872DebuggerSpecific(base);
+ if ( debugExec=="16F7X7" ) return new P16F7X7DebuggerSpecific(base);
+ return new P16F87XDebuggerSpecific(base);
+ case Pic::Architecture::P17C:
+ case Pic::Architecture::P18C:
+ case Pic::Architecture::P18F:
+ case Pic::Architecture::P18J: return new P18FDebuggerSpecific(base);
+ case Pic::Architecture::P10X:
+ case Pic::Architecture::P24F:
+ case Pic::Architecture::P24H:
+ case Pic::Architecture::P30F:
+ case Pic::Architecture::P33F:
+ case Pic::Architecture::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return 0;
+}
diff --git a/src/progs/icd2/base/icd2_debug.h b/src/progs/icd2/base/icd2_debug.h
new file mode 100644
index 0000000..bd2a6fe
--- /dev/null
+++ b/src/progs/icd2/base/icd2_debug.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_DEBUG_H
+#define ICD2_DEBUG_H
+
+#include "icd2_prog.h"
+#include "devices/pic/prog/pic_debug.h"
+
+namespace Icd2
+{
+class DebuggerSpecific;
+
+//-----------------------------------------------------------------------------
+class DebugProgrammer : public ProgrammerBase
+{
+Q_OBJECT
+public:
+ DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data);
+ bool readDebugExecutiveVersion();
+ const VersionData &debugExecutiveVersion() const { return _debugExecutiveVersion; }
+
+private:
+ VersionData _debugExecutiveVersion;
+ Device::Array _deArray;
+ uint _deStart, _deEnd;
+
+ virtual void clear();
+ virtual bool internalSetupHardware();
+ virtual bool doProgram(const Device::Memory &memory, const Device::MemoryRange &range);
+ virtual bool programAll(const Pic::Memory &memory);
+ virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const ::Programmer::VerifyData *vdata);
+
+ bool getDebugExecutive();
+ bool writeDebugExecutive();
+ Pic::Memory toDebugMemory(const Pic::Memory &memory, bool withDebugExecutive);
+};
+
+//-----------------------------------------------------------------------------
+class Debugger : public ::Debugger::PicBase
+{
+public:
+ Debugger(DebugProgrammer &programmer) : ::Debugger::PicBase(programmer) {}
+ virtual bool setBreakpoints(const QValueList<Address> &addresses);
+ Hardware *hardware() { return static_cast<Hardware *>(_programmer.hardware()); }
+ DebugProgrammer &programmer() { return static_cast<DebugProgrammer &>(_programmer); }
+ DebuggerSpecific *specific();
+ bool waitForTargetMode(Pic::TargetMode mode);
+ virtual bool readRegister(const Register::TypeData &data, BitValue &value);
+ virtual bool writeRegister(const Register::TypeData &data, BitValue value);
+ bool init(bool last);
+
+protected:
+ virtual bool internalInit();
+ virtual bool internalRun();
+ virtual bool internalStep();
+ virtual bool softHalt(bool &success);
+ virtual bool hardHalt();
+ virtual bool internalReset();
+ virtual bool updateState();
+
+private:
+ bool _initLast;
+};
+
+//-----------------------------------------------------------------------------
+class DebuggerGroup : public Group
+{
+public:
+ virtual QString name() const { return "icd2_debugger"; }
+ virtual QString label() const { return i18n("ICD2 Debugger"); }
+ virtual ::Programmer::Properties properties() const { return Group::properties() | ::Programmer::Debugger; }
+ virtual uint maxNbBreakpoints(const Device::Data *) const { return 1; }
+
+protected:
+ virtual void addDevice(const QString &name, const Device::Data *data, ::Group::Support support);
+ virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new DebugProgrammer(*this, static_cast<const Pic::Data *>(data)); }
+ virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast<DebugProgrammer &>(base)); }
+ virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &base) const;
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_debug_specific.cpp b/src/progs/icd2/base/icd2_debug_specific.cpp
new file mode 100644
index 0000000..56cc178
--- /dev/null
+++ b/src/progs/icd2/base/icd2_debug_specific.cpp
@@ -0,0 +1,255 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_debug_specific.h"
+
+#include "devices/pic/base/pic_register.h"
+#include "icd2_data.h"
+
+//----------------------------------------------------------------------------
+Address Icd2::P16FDebuggerSpecific::addressWREG() const
+{
+ return FAMILY_DATA[family(device()->name())].wreg;
+}
+
+Address Icd2::P16FDebuggerSpecific::addressRegister(Address address) const
+{
+ QString name = device()->registersData().sfrNames[address];
+ if ( name=="FSR" ) return FAMILY_DATA[family(device()->name())].fsr;
+ if ( name=="STATUS" ) return FAMILY_DATA[family(device()->name())].status;
+ return address;
+}
+
+bool Icd2::P16FDebuggerSpecific::reset()
+{
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ return init(true);
+}
+
+bool Icd2::P16FDebuggerSpecific::setBreakpoint(Address address)
+{
+ if ( !address.isValid() ) address = 0x1FFF; // outside memory range
+ BitValue value = address.toUInt() | 0x8000; // read-only INBUG bit
+ return hardware()->writeRegister(0x18E, value, 2);
+}
+
+bool Icd2::P16FDebuggerSpecific::readBreakpoint(BitValue &value)
+{
+ if ( !hardware()->readRegister(0x18E, value, 2) ) return false;
+ value = value.maskWith(0x1FFF);
+ return true;
+}
+
+bool Icd2::P16FDebuggerSpecific::beginInit(Device::Array *saved)
+{
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ double vdd;
+ if ( !hardware()->readVoltage(Pic::TargetVdd, vdd) ) return false;
+ log(Log::DebugLevel::Normal, QString(" Target Vdd: %1 V").arg(vdd));
+
+ if (saved) {
+ saved->resize(1);
+ if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, 0, *saved, 0) ) return false; // save first instruction
+ if ( (*saved)[0]!=device()->nopInstruction() ) log(Log::LineType::Warning, i18n(" According to ICD2 manual, instruction at address 0x0 should be \"nop\"."));
+ }
+
+ return true;
+}
+
+bool Icd2::P16FDebuggerSpecific::endInit(BitValue expectedPC)
+{
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false;
+ BitValue value;
+ if ( !readBreakpoint(value) ) return false;
+ if ( value==expectedPC+1 ) {
+ // #### happen for some custom icd2 or sometimes when we had to force a halt (?)
+ expectedPC = expectedPC+1;
+ //log(Log::LineType::Information, i18n("Detected custom ICD2"));
+ }
+ if ( value!=expectedPC ) {
+ log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4)));
+ return false;
+ }
+ if ( !setBreakpoint(0x0000) ) return false;
+
+ if ( !base().update() ) return false;
+ if ( base().pc()!=expectedPC ) {
+ log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4)));
+ return false;
+ }
+ return true;
+}
+
+bool Icd2::P16F872DebuggerSpecific::init(bool)
+{
+ Device::Array saved;
+ if ( !beginInit(&saved) ) return false;
+
+ // this seems to be needed
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false;
+ Pic::TargetMode mode;
+ if ( !programmer().getTargetMode(mode) ) return false;
+
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false;
+ log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target.");
+ Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector
+ if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false;
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device
+ if ( !base().waitForTargetMode(Pic::TargetRunning) ) return false;
+ log(Log::DebugLevel::Normal, " Try to halt target.");
+ if ( !hardware()->haltRun() ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false;
+ if ( !programmer().readDebugExecutiveVersion() ) return false;
+ log(Log::DebugLevel::Normal, " Set breakpoint at reset vector.");
+ if ( !setBreakpoint(0x0000) ) return false;
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false;
+ log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target.");
+ if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction
+ if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false;
+
+ return endInit(0x0001);
+}
+
+bool Icd2::P16F87XDebuggerSpecific::init(bool)
+{
+ Device::Array saved;
+ if ( !beginInit(&saved) ) return false;
+
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false;
+ log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target.");
+ Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector
+ if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false;
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device
+ Pic::TargetMode mode;
+ if ( !programmer().getTargetMode(mode) ) return false;
+ if ( mode==Pic::TargetRunning && !hardware()->haltRun() ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false;
+ if ( !programmer().readDebugExecutiveVersion() ) return false;
+ log(Log::DebugLevel::Normal, " Set breakpoint at reset vector.");
+ if ( !setBreakpoint(0x0000) ) return false;
+ if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false;
+ log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target.");
+ if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction
+ if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false;
+
+ return endInit(0x0001);
+}
+
+bool Icd2::P16F7X7DebuggerSpecific::init(bool last)
+{
+ Device::Array saved;
+ if ( !beginInit(last ? &saved : 0) ) return false;
+
+ log(Log::DebugLevel::Normal, " Run target.");
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false;
+ if ( !programmer().readDebugExecutiveVersion() ) return false;
+
+ BitValue value;
+ if ( !readBreakpoint(value) ) return false;
+ BitValue expectedPC = (last ? 0x0001 : 0x0000);
+ if ( value==expectedPC+1 ) {
+ expectedPC = expectedPC+1;
+ log(Log::DebugLevel::Normal, "Probably detected custom ICD2");
+ }
+ if ( value!=expectedPC )
+ log(Log::DebugLevel::Normal, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4)));
+ if ( !setBreakpoint(0x0000) ) return false;
+
+ if ( !base().update() ) return false;
+ // #### not sure if there is a better way to get initial values (we are stopped here...)
+ Register::list().setValue(base().pcTypeData(), value);
+ Register::list().setValue(base().registerTypeData("STATUS"), 0x0);
+ Register::list().setValue(deviceSpecific()->wregTypeData(), 0x0);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+Icd2::P18FDebuggerSpecific::P18FDebuggerSpecific(::Debugger::Base &base)
+ : DebuggerSpecific(base)
+{
+ const Pic::RegistersData &rdata = device()->registersData();
+ // find last used bank (but not #15)
+ _reservedBank = rdata.nbBanks - 1; // #14
+ for (uint i=1; i<rdata.nbBanks-1; i++) {
+ if ( rdata.isBankUsed(i) ) continue;
+ _reservedBank = i - 1;
+ break;
+ }
+ // check it's not a bank for CAN
+ for (; _reservedBank>0; _reservedBank--)
+ if ( !rdata.bankHasSfrs(_reservedBank) ) break;
+ // also take care of USB RAM
+ if ( (device()->architecture()==Pic::Architecture::P18F || device()->architecture()==Pic::Architecture::P18J)
+ && device()->hasFeature(Pic::Feature::USB) ) {
+ if ( _reservedBank==7 ) _reservedBank = 3; // 18F2455 family: 4 USB RAM banks
+ // 18F87J50 family ?
+ }
+}
+
+Address Icd2::P18FDebuggerSpecific::addressWREG()const
+{
+ return reservedRegisterOffset() | 0x0FF;
+}
+
+Address Icd2::P18FDebuggerSpecific::addressRegister(Address address) const
+{
+ QString name = device()->registersData().sfrNames[address];
+ if ( name=="PCLATU" ) return reservedRegisterOffset() | 0x0F4;
+ if ( name=="PCLATH" ) return reservedRegisterOffset() | 0x0F5;
+ if ( name=="FSR0H" ) return reservedRegisterOffset() | 0x0FB;
+ if ( name=="FSR0L" ) return reservedRegisterOffset() | 0x0FC;
+ if ( name=="BSR" ) return reservedRegisterOffset() | 0x0FD;
+ if ( name=="STATUS" ) return reservedRegisterOffset() | 0x0FE;
+ return address;
+}
+
+bool Icd2::P18FDebuggerSpecific::setBreakpoint(Address address)
+{
+ BitValue value = (address.isValid() ? address.toUInt() << 15 : 0x0FFFFF00); // ??
+ return hardware()->writeRegister(0xFB6, value, 4);
+}
+
+bool Icd2::P18FDebuggerSpecific::readBreakpoint(BitValue &value)
+{
+ if ( !hardware()->readRegister(0xFB6, value, 4) ) return false;
+ value >>= 15;
+ return true;
+}
+
+bool Icd2::P18FDebuggerSpecific::reset()
+{
+ if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ??
+ if ( !hardware()->writeRegister(0xFB5, 0x01, 1) ) return false; // #### ??
+ if ( !hardware()->command("2D", 0) ) return false; // reset
+ if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ??
+ if ( !base().update() ) return false;
+ BitValue expectedPC = 0x0000;
+ if ( base().pc()==0x0001) {
+ expectedPC = 0x0001;
+ log(Log::LineType::Information, i18n("Detected custom ICD2"));
+ }
+ if ( base().pc()!=expectedPC ) {
+ log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4)));
+ return false;
+ }
+ return true;
+}
+
+bool Icd2::P18FDebuggerSpecific::init(bool)
+{
+ if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false;
+ if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false;
+ return reset();
+}
diff --git a/src/progs/icd2/base/icd2_debug_specific.h b/src/progs/icd2/base/icd2_debug_specific.h
new file mode 100644
index 0000000..d14887b
--- /dev/null
+++ b/src/progs/icd2/base/icd2_debug_specific.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_DEBUG_SPECIFIC_H
+#define ICD2_DEBUG_SPECIFIC_H
+
+#include "icd2_debug.h"
+
+namespace Icd2
+{
+//-----------------------------------------------------------------------------
+class DebuggerSpecific : public ::Debugger::Specific
+{
+public:
+ DebuggerSpecific(::Debugger::Base &base) : ::Debugger::Specific(base) {}
+ Debugger &base() { return static_cast<Debugger &>(_base); }
+ const Debugger &base() const { return static_cast<const Debugger &>(_base); }
+ const Pic::Data *device() const { return base().device(); }
+ Hardware *hardware() { return base().programmer().hardware(); }
+ DebugProgrammer &programmer() { return base().programmer(); }
+ ::Debugger::PicSpecific *deviceSpecific() { return base().deviceSpecific(); }
+ virtual Address addressWREG() const = 0;
+ virtual BitValue maskPC() const = 0;
+ virtual Address addressRegister(Address address) const = 0;
+ virtual bool setBreakpoint(Address address) = 0;
+ virtual bool readBreakpoint(BitValue &value) = 0;
+ virtual bool init(bool last) = 0;
+ virtual bool reset() = 0;
+};
+
+//-----------------------------------------------------------------------------
+class P16FDebuggerSpecific : public DebuggerSpecific
+{
+public:
+ P16FDebuggerSpecific(::Debugger::Base &base) : DebuggerSpecific(base) {}
+ virtual Address addressBreakpointRegister() const { return 0x18E; }
+ virtual BitValue writeMaskBreakpointRegister() const { return 0x8000; }
+ virtual BitValue readMaskBreakpointRegister() const { return 0x1FFF; }
+ virtual Address addressWREG() const;
+ virtual BitValue maskPC() const { return 0x1FFF; }
+ virtual Address addressRegister(Address address) const;
+ virtual bool setBreakpoint(Address address);
+ virtual bool readBreakpoint(BitValue &value);
+ virtual bool reset();
+
+protected:
+ bool beginInit(Device::Array *saved);
+ bool endInit(BitValue expectedPC);
+};
+
+class P16F872DebuggerSpecific : public P16FDebuggerSpecific
+{
+public:
+ P16F872DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {}
+ virtual bool init(bool last);
+};
+
+class P16F87XDebuggerSpecific : public P16FDebuggerSpecific
+{
+public:
+ P16F87XDebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {}
+ virtual bool init(bool last);
+};
+
+class P16F7X7DebuggerSpecific : public P16FDebuggerSpecific
+{
+public:
+ P16F7X7DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {}
+ virtual bool init(bool last);
+};
+
+//-----------------------------------------------------------------------------
+class P18FDebuggerSpecific : public DebuggerSpecific
+{
+public:
+ P18FDebuggerSpecific(::Debugger::Base &base);
+ virtual Address addressWREG() const;
+ virtual BitValue maskPC() const { return 0xFFFF; }
+ virtual Address addressRegister(Address address) const;
+ virtual bool setBreakpoint(Address address);
+ virtual bool readBreakpoint(BitValue &value);
+ virtual bool init(bool last);
+ virtual bool reset();
+ uint reservedBank() const { return _reservedBank; }
+
+private:
+ uint _reservedBank; // bank where are the debugging sfrs
+ uint reservedRegisterOffset() const { return reservedBank() << 8; }
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_prog.cpp b/src/progs/icd2/base/icd2_prog.cpp
new file mode 100644
index 0000000..7b2a59b
--- /dev/null
+++ b/src/progs/icd2/base/icd2_prog.cpp
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_prog.h"
+
+#include "common/global/pfile.h"
+#include "progs/base/prog_config.h"
+#include "devices/list/device_list.h"
+#include "icd2_serial.h"
+#include "icd2_usb.h"
+#include "icd2_data.h"
+
+//-----------------------------------------------------------------------------
+void Icd2::ProgrammerBase::clear()
+{
+ Icd::ProgrammerBase::clear();
+ _firmwareId = 0;
+ _testData = TestData();
+}
+
+bool Icd2::ProgrammerBase::readFirmwareVersion()
+{
+ if ( !hardware()->setup() ) return false;
+ if ( !Icd::ProgrammerBase::readFirmwareVersion() ) return false;
+ _firmwareId = hardware()->getFirmwareId();
+ return !hasError();
+}
+
+bool Icd2::ProgrammerBase::internalSetupHardware()
+{
+ ::Programmer::Config config;
+ if ( !_targetSelfPowered && device()->architecture()==Pic::Architecture::P30F
+ && !askContinue(i18n("It is not recommended to power dsPICs from ICD. Continue anyway?")) ) {
+ logUserAbort();
+ return false;
+ }
+ return Icd::ProgrammerBase::internalSetupHardware();
+}
+
+bool Icd2::ProgrammerBase::selfTest(bool ask)
+{
+ log(Log::DebugLevel::Normal, " Self-test");
+ if ( !hardware()->selfTest(_testData) ) return false;
+ if ( !_testData.pass() ) {
+ QString s;
+ for (uint i=0; i<TestData::Nb_VoltageTypes; i++) {
+ if ( i!=0 ) s += "; ";
+ s += _testData.pretty(TestData::VoltageType(i));
+ }
+ log(Log::LineType::Warning, i18n("Self-test failed: %1").arg(s));
+ if ( ask && !askContinue(i18n("Self-test failed (%1). Do you want to continue anyway?").arg(s)) ) {
+ logUserAbort();
+ return false;
+ }
+ }
+ return !hasError();
+}
+
+VersionData Icd2::ProgrammerBase::firmwareVersion(::Programmer::FirmwareVersionType type) const
+{
+ const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA);
+ const Version &v = vd->version[_firmwareId-1];
+ return VersionData(v.major, v.minor, v.dot);
+}
+
+VersionData Icd2::ProgrammerBase::mplabVersion(::Programmer::FirmwareVersionType type) const
+{
+ const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA);
+ return VersionData(vd->mplabMajor, vd->mplabMinor, 0);
+}
+
+bool Icd2::ProgrammerBase::setupFirmware()
+{
+ const FamilyData &fdata = FAMILY_DATA[family(device()->name())];
+ log(Log::DebugLevel::Normal, QString(" Firmware id is %1 and we want %2").arg(_firmwareId).arg(fdata.efid));
+ if ( fdata.efid==_firmwareId ) return true;
+ log(Log::LineType::Information, i18n(" Incorrect firmware loaded."));
+
+ // find firmware file
+ PURL::Directory dir = firmwareDirectory();
+ if ( dir.isEmpty() ) return false;
+ QString nameFilter = "ICD" + QString::number(fdata.efid).rightJustify(2, '0') + "??????.hex";
+ QStringList files = dir.files(nameFilter);
+ if ( files.isEmpty() ) {
+ log(Log::LineType::Error, i18n("Could not find firmware file \"%1\" in directory \"%2\".").arg(nameFilter).arg(dir.path()));
+ return false;
+ }
+
+ // upload hex file
+ PURL::Url url(dir, files[files.count()-1]);
+ log(Log::DebugLevel::Normal, QString(" Firmware file: %1").arg(url.pretty()));
+ Log::StringView sview;
+ PURL::File file(url, sview);
+ if ( !file.openForRead() ) {
+ log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty()));
+ return false;
+ }
+ if ( !doUploadFirmware(file) ) return false;
+
+ // check firmware
+ if ( !readFirmwareVersion() ) return false;
+ if ( fdata.efid!=_firmwareId ) {
+ log(Log::LineType::Error, i18n("Firmware still incorrect after uploading."));
+ return false;
+ }
+ log(Log::LineType::Information, i18n(" Firmware succesfully uploaded."));
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+Icd2::Programmer::Programmer(const ::Programmer::Group &group, const Pic::Data *data)
+ : Icd2::ProgrammerBase(group, data, "icd2_programmer")
+{}
+
+//----------------------------------------------------------------------------
+Programmer::Properties Icd2::Group::properties() const
+{
+ return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware
+ | ::Programmer::NeedDeviceSpecificFirmware | ::Programmer::CanReleaseReset
+ | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState;
+}
+
+bool Icd2::Group::canReadVoltage(Pic::VoltageType type) const
+{
+ return ( type==Pic::ProgrammerVpp || type==Pic::TargetVdd || type==Pic::TargetVpp );
+}
+
+Programmer::Hardware *Icd2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const
+{
+ if ( hd.port.type==PortType::Serial ) return new SerialHardware(base, hd.port.device);
+ return new USBHardware(base);
+}
+
+Programmer::DeviceSpecific *Icd2::Group::createDeviceSpecific(::Programmer::Base &base) const
+{
+ return new Icd::DeviceSpecific(base);
+}
diff --git a/src/progs/icd2/base/icd2_prog.h b/src/progs/icd2/base/icd2_prog.h
new file mode 100644
index 0000000..e8be727
--- /dev/null
+++ b/src/progs/icd2/base/icd2_prog.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_PROG_H
+#define ICD2_PROG_H
+
+#include "common/global/global.h"
+#include "icd_prog.h"
+#include "icd2.h"
+#include "progs/base/prog_group.h"
+
+namespace Icd2
+{
+class Hardware;
+
+//-----------------------------------------------------------------------------
+class ProgrammerBase : public Icd::ProgrammerBase
+{
+Q_OBJECT
+public:
+ ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name)
+ : Icd::ProgrammerBase(group, data, name) {}
+ Hardware *hardware() { return static_cast<Hardware *>(_hardware); }
+ const TestData &testData() const { return _testData; }
+ virtual bool selfTest(bool ask);
+ virtual bool readFirmwareVersion();
+ uchar firmwareId() const { return _firmwareId; }
+ virtual bool setTarget() { return hardware()->setTarget(); }
+
+protected:
+ virtual void clear();
+ virtual bool setupFirmware();
+ virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const;
+ virtual VersionData mplabVersion(Programmer::FirmwareVersionType type) const;
+ virtual bool internalSetupHardware();
+
+private:
+ uchar _firmwareId;
+ TestData _testData;
+};
+
+//-----------------------------------------------------------------------------
+class Programmer : public ProgrammerBase
+{
+Q_OBJECT
+public:
+ Programmer(const ::Programmer::Group &group, const Pic::Data *data);
+};
+
+//-----------------------------------------------------------------------------
+class Group : public Icd::Group
+{
+public:
+ virtual QString xmlName() const { return "icd2"; }
+ virtual ::Programmer::Properties properties() const;
+ virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetPowerModeFromConfig; }
+ virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::USB ); }
+ virtual bool canReadVoltage(Pic::VoltageType type) const;
+
+protected:
+ virtual void initSupported();
+ virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const;
+ virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const;
+};
+
+//-----------------------------------------------------------------------------
+class ProgrammerGroup : public Group
+{
+public:
+ virtual QString name() const { return "icd2"; }
+ virtual QString label() const { return i18n("ICD2 Programmer"); }
+
+protected:
+ virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast<const Pic::Data *>(data)); }
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_serial.cpp b/src/progs/icd2/base/icd2_serial.cpp
new file mode 100644
index 0000000..1ab738c
--- /dev/null
+++ b/src/progs/icd2/base/icd2_serial.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_serial.h"
+
+#include "common/global/global.h"
+#include "common/common/misc.h"
+
+//-----------------------------------------------------------------------------
+Icd2::SerialPort::SerialPort(const QString &device, Log::Base &log)
+ : Port::Serial(device, NeedDrain | NeedFlush, log)
+{}
+
+bool Icd2::SerialPort::open(Speed speed)
+{
+ if ( !Port::Serial::open() ) return false;
+ return setMode(NoInputFlag, ByteSize8 | EnableReceiver | HardwareFlowControl, speed, 0);
+}
+
+//-----------------------------------------------------------------------------
+Icd2::SerialHardware::SerialHardware(::Programmer::Base &base, const QString &portDevice)
+ : Hardware(base, new SerialPort(portDevice, base))
+{}
+
+bool Icd2::SerialHardware::internalConnect(const QString &mode)
+{
+ if ( !static_cast<SerialPort *>(_port)->open(Port::Serial::S19200) ) return false;
+ if ( !reset() ) return false;
+ if ( !_port->send("Z", 1) ) return false;
+ QString s;
+ if ( !_port->receive(4, s) ) return false;
+ if ( !reset() ) return false;
+ QByteArray a = toAscii(mode);
+ if ( !_port->send(a.data(), a.count()) ) return false;
+ if ( !_port->receive(1, s) ) return false;
+ if ( s.upper()!=mode ) {
+ log(Log::LineType::Error, i18n("Failed to set port mode to '%1'.").arg(mode));
+ return false;
+ }
+ //log(Log::Debug, "set fast speed");
+ //if ( !setFastSpeed() ) return false;
+ return true;
+}
+
+bool Icd2::SerialHardware::reset()
+{
+ static_cast<Port::Serial *>(_port)->setPinOn(Port::Serial::DTR, false, Port::PositiveLogic); // Trigger DTR to reset icd2
+ Port::msleep(10);
+ static_cast<Port::Serial *>(_port)->setPinOn(Port::Serial::DTR, true, Port::PositiveLogic); // remove reset
+ Port::msleep(10);
+ return true;
+}
+
+bool Icd2::SerialHardware::setFastSpeed()
+{
+ if ( !command("4D", 0) ) return false; // go faster
+ static_cast<SerialPort *>(_port)->open(Port::Serial::S57600);
+ Port::msleep(100); // ...we do need to delay here
+ return !hasError();
+}
diff --git a/src/progs/icd2/base/icd2_serial.h b/src/progs/icd2/base/icd2_serial.h
new file mode 100644
index 0000000..546e7b3
--- /dev/null
+++ b/src/progs/icd2/base/icd2_serial.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2002-2003 Stephen Landamore <stephen@landamore.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_SERIAL_H
+#define ICD2_SERIAL_H
+
+#include "icd2.h"
+#include "common/port/serial.h"
+
+namespace Icd2
+{
+
+//-----------------------------------------------------------------------------
+class SerialPort : public Port::Serial
+{
+public:
+ SerialPort(const QString &portDevice, Log::Base &log);
+ bool open(Speed speed);
+};
+
+//-----------------------------------------------------------------------------
+class SerialHardware : public Hardware
+{
+public:
+ SerialHardware(::Programmer::Base &base, const QString &portDevice);
+
+private:
+ bool setFastSpeed();
+ bool reset();
+ virtual bool internalConnect(const QString &mode);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_usb.cpp b/src/progs/icd2/base/icd2_usb.cpp
new file mode 100644
index 0000000..945ef6f
--- /dev/null
+++ b/src/progs/icd2/base/icd2_usb.cpp
@@ -0,0 +1,174 @@
+/***************************************************************************
+ * Copyright (C) 2005 Lorenz M�senlechner & Matthias Kranz *
+ * <icd2linux@hcilab.org> *
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_usb.h"
+
+#include "microchip.h"
+#include "common/common/misc.h"
+
+//------------------------------------------------------------------------------
+const Icd2::USBPort::SequenceData Icd2::USBPort::SEQUENCE_DATA[Nb_SequenceTypes] = {
+ { 0x00 }, // receive
+ { 0x01 }, // send
+ { 0x02 }, // connect
+ { 0x00 } // poll
+};
+
+Icd2::USBPort::USBPort(uint deviceId, Log::Base &log)
+ : Port::USB(log, Microchip::VENDOR_ID, deviceId, 1, 0), _dataSend(false)
+{}
+
+bool Icd2::USBPort::doSequence(SequenceType type, char *data, uint size)
+{
+ QByteArray tx(0x12);
+ for (uint i=0; i<uint(tx.count()); i++) tx[i] = 0x00;
+ tx[0x00] = SEQUENCE_DATA[type].type;
+ tx[0x01] = _seqnum;
+ tx[0x02] = size & 0xFF;
+ tx[0x03] = (size >> 8) & 0xFF;
+ tx[0x0A] = _ctype & 0xFF;
+ tx[0x0B] = (_ctype >> 8) & 0xFF;
+ if ( !write(0x01, tx.data(), tx.size()) ) return false;
+
+ switch (type) {
+ case Connect: break;
+ case Receive:
+ if ( !read(0x82, data, size, 0) ) return false;
+ break;
+ case Poll:
+ if ( !read(0x82, data, size, &_poll) ) return false;
+ break;
+ case Send:
+ if ( !write(0x01, data, size) ) return false;
+ break;
+ case Nb_SequenceTypes: Q_ASSERT(false); break;
+ }
+
+ QByteArray rx(0x08);
+ if ( !read(0x81, rx.data(), rx.size(), 0) ) return false;
+ //Q_ASSERT( rx[0]==tx[1] );
+
+ _seqnum++;
+ if ( _seqnum==0xFF ) _seqnum = 0xC0;
+ return true;
+}
+
+bool Icd2::USBPort::connectDevice(const QString &mode)
+{
+ _seqnum = 0xC1; // preset seqnum
+
+ _ctype = 0x00;
+ if ( !doSequence(Connect, 0, 0) ) return false;
+ if ( !send("Z", 1) ) return false;
+ QString s;
+ if ( !receive(4, s) ) return false;
+
+ _ctype = 0x00;
+ if ( !doSequence(Connect, 0, 0) ) return false;
+ for (uint i=0; true; i++) {
+ if ( i==10 ) {
+ log(Log::LineType::Error, i18n("Problem connecting ICD2: please try again after unplug-replug."));
+ return false;
+ }
+ _ctype = 0x02;
+ QByteArray a = toAscii(mode);
+ if ( !doSequence(Send, a.data(), a.count()) ) return false;
+ char c;
+ _ctype = 0x02;
+ if ( !doSequence(Receive, &c, 1) ) return false;
+ if ( c==mode.lower()[0] ) break;
+ }
+
+ return true;
+}
+
+bool Icd2::USBPort::internalReceive(uint size, char *data, uint)
+{
+ if (_dataSend) {
+ //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2)
+ _ctype = 0xC9;
+ } else _ctype = 0xC9;
+ bool ok = doSequence(Receive, data, size);
+ if (_dataSend) _dataSend = false;
+ return ok;
+}
+
+bool Icd2::USBPort::internalSend(const char *data, uint size, uint)
+{
+ if (_dataSend) {
+ //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2)
+ _ctype = 0xC9;
+ } else _ctype = 0xC9;
+ bool ok = doSequence(Send, (char *)data, size);
+ if (_dataSend) _dataSend = false;
+ return ok;
+}
+
+bool Icd2::USBPort::poll(uint size, QString &s)
+{
+ QMemArray<uchar> a;
+ if ( !poll(size, a) ) return false;
+ s.fill(0, size);
+ for (uint i=0; i<size; i++) s[i] = a[i];
+ return true;
+}
+
+bool Icd2::USBPort::poll(uint size, QMemArray<uchar> &a)
+{
+ a.resize(size);
+ for (;;) {
+ _ctype = 0x65;//0x01;
+ if ( !doSequence(Poll, (char *)a.data(), size) ) return false;
+ if (_poll) break;
+ }
+ //log(Log::DebugLevel::Max, QString("Receiced: \"%1\"").arg(toPrintable((const char *)a.data(), size)));
+ return true;
+}
+
+bool Icd2::USBPort::dataSend(const char *data, uint size)
+{
+ _dataSend = true;
+ return Port::USB::send(data, size);
+}
+
+bool Icd2::USBPort::dataReceive(uint size, QString &s)
+{
+ _dataSend = true;
+ return Port::USB::receive(size, s);
+}
+
+//------------------------------------------------------------------------------
+Icd2::USBHardware::USBHardware(::Programmer::Base &base)
+ : Hardware(base, new USBPort(ID_CLIENT, base))
+{}
+
+bool Icd2::USBHardware::internalConnect(const QString &mode)
+{
+ // load control messages for USB device if needed
+ log(Log::DebugLevel::Extra, QString("need firmware ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE)!=0));
+ if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE) ) {
+ USBPort port(ID_FIRMWARE, *this);
+ if ( !port.open() ) return false;
+ uint i = 0;
+ while ( CONTROL_MESSAGE_DATA[i].bytes!=0 ) {
+ if ( !port.sendControlMessage(CONTROL_MESSAGE_DATA[i]) ) return false;
+ i++;
+ }
+ port.close();
+ for (uint i=0; i<10; i++) {
+ log(Log::DebugLevel::Extra, QString("client here ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_CLIENT)!=0));
+ if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_CLIENT) ) break;
+ Port::msleep(1000);
+ }
+ }
+
+ if ( !_port->open() ) return false;
+ return static_cast<USBPort *>(_port)->connectDevice(mode);
+}
diff --git a/src/progs/icd2/base/icd2_usb.h b/src/progs/icd2/base/icd2_usb.h
new file mode 100644
index 0000000..c2677a6
--- /dev/null
+++ b/src/progs/icd2/base/icd2_usb.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz *
+ * <icd2linux@hcilab.org> *
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD2_USB_H
+#define ICD2_USB_H
+
+#include "icd2.h"
+#include "common/port/usb_port.h"
+
+namespace Icd2
+{
+
+//-----------------------------------------------------------------------------
+class USBPort : public Port::USB
+{
+public:
+ USBPort(uint deviceId, Log::Base &log);
+ bool connectDevice(const QString &mode);
+ bool poll(uint size, QString &s);
+ bool poll(uint size, QMemArray<uchar> &data);
+ bool dataSend(const char *data, uint size);
+ bool dataReceive(uint size, QString &s);
+
+private:
+ uchar _seqnum;
+ bool _poll;
+ uint _ctype;
+ bool _dataSend;
+
+ enum SequenceType { Receive = 0, Send, Connect, Poll, Nb_SequenceTypes };
+ struct SequenceData {
+ char type;
+ };
+ static const SequenceData SEQUENCE_DATA[Nb_SequenceTypes];
+ bool doSequence(SequenceType type, char *data, uint size);
+ virtual bool internalSend(const char *data, uint size, uint timeout = 0);
+ virtual bool internalReceive(uint size, char *data, uint timeout = 0);
+};
+
+//------------------------------------------------------------------------------
+class USBHardware : public Hardware
+{
+public:
+ USBHardware(::Programmer::Base &base);
+
+private:
+ static const Port::USB::ControlMessageData CONTROL_MESSAGE_DATA[];
+ enum { ID_FIRMWARE = 0x8000, // ICD2 id before usb firmware is transmitted
+ ID_CLIENT = 0x8001 // ICD2 id after firmware is transmitted
+ };
+ virtual bool internalConnect(const QString &mode);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/icd2_usb_firmware.cpp b/src/progs/icd2/base/icd2_usb_firmware.cpp
new file mode 100644
index 0000000..c7947cf
--- /dev/null
+++ b/src/progs/icd2/base/icd2_usb_firmware.cpp
@@ -0,0 +1,613 @@
+/***************************************************************************
+ * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz *
+ * <icd2linux@hcilab.org> *
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd2_usb.h"
+
+const Port::USB::ControlMessageData Icd2::USBHardware::CONTROL_MESSAGE_DATA[] = {
+{ 0x40, 0xA0, 0x7F92, "01" },
+{ 0x40, 0xA0, 0x146C, "C200907FA5E05418FF131313541F4450" },
+{ 0x40, 0xA0, 0x147C, "F51C139201D2E8907FAB74FFF0907FA9" },
+{ 0x40, 0xA0, 0x148C, "F0907FAAF05391EF907F95E044C0F090" },
+{ 0x40, 0xA0, 0x149C, "7FAFE04401F0907FAEE04405F0D2AF12" },
+{ 0x40, 0xA0, 0x14AC, "175F3000FD121100C20080F622" },
+{ 0x40, 0xA0, 0x1100, "907FE9E0245D600D1470030212442402" },
+{ 0x40, 0xA0, 0x1110, "600302124A907FEAE0750800F509A3E0" },
+{ 0x40, 0xA0, 0x1120, "FEE42509F509EE3508F508907FEEE075" },
+{ 0x40, 0xA0, 0x1130, "0A00F50BA3E0FEE4250BF50BEE350AF5" },
+{ 0x40, 0xA0, 0x1140, "0A907FE8E064C060030211D4E50B450A" },
+{ 0x40, 0xA0, 0x1150, "700302124AC3E50B9440E50A94005008" },
+{ 0x40, 0xA0, 0x1160, "850A0C850B0D8006750C00750D40907F" },
+{ 0x40, 0xA0, 0x1170, "E9E0B4A325AE0CAF0DAA08A9097B01C0" },
+{ 0x40, 0xA0, 0x1180, "03C002C0017A7F790078007C7FAD03D0" },
+{ 0x40, 0xA0, 0x1190, "01D002D003121356800FAF09AE08AD0D" },
+{ 0x40, 0xA0, 0x11A0, "7A7F79007B001215A4907FB5E50DF0E5" },
+{ 0x40, 0xA0, 0x11B0, "0D2509F509E50C3508F508C3E50B950D" },
+{ 0x40, 0xA0, 0x11C0, "F50BE50A950CF50A907FB4E020E20302" },
+{ 0x40, 0xA0, 0x11D0, "114C80F4907FE8E06440706EE50B450A" },
+{ 0x40, 0xA0, 0x11E0, "6068E4907FC5F0907FB4E020E3F9907F" },
+{ 0x40, 0xA0, 0x11F0, "C5E0750C00F50D907FE9E0B4A315AE0C" },
+{ 0x40, 0xA0, 0x1200, "AF0DA809AC087D017B017A7E79C01213" },
+{ 0x40, 0xA0, 0x1210, "56800FAF09AE08AD0D7A7F79007B0012" },
+{ 0x40, 0xA0, 0x1220, "14B9E50D2509F509E50C3508F508C3E5" },
+{ 0x40, 0xA0, 0x1230, "0B950DF50BE50A950CF50A907FB4E044" },
+{ 0x40, 0xA0, 0x1240, "02F08098907FEAE0F51C" },
+{ 0x40, 0xA0, 0x124A, "22" },
+{ 0x40, 0xA0, 0x1558, "AB07AA06AC05" },
+{ 0x40, 0xA0, 0x155E, "E4FD300111EAFFAE050DEE2400F582E4" },
+{ 0x40, 0xA0, 0x156E, "34E0F583EFF0EBAE050D74002EF582E4" },
+{ 0x40, 0xA0, 0x157E, "34E0F583EBF0AF050D74002FF582E434" },
+{ 0x40, 0xA0, 0x158E, "E0F583ECF0AF1C7AE07B001217207F0A" },
+{ 0x40, 0xA0, 0x159E, "7E0012173C" },
+{ 0x40, 0xA0, 0x15A3, "22" },
+{ 0x40, 0xA0, 0x14B9, "8E0E8F0F8D108A118B12" },
+{ 0x40, 0xA0, 0x14C3, "E4F513E513C395105020050FE50FAE0E" },
+{ 0x40, 0xA0, 0x14D3, "7002050E14FFE5122513F582E43511F5" },
+{ 0x40, 0xA0, 0x14E3, "83E0FD121558051380D9" },
+{ 0x40, 0xA0, 0x14ED, "22" },
+{ 0x40, 0xA0, 0x15A4, "8E0E8F0F8D108A118B12" },
+{ 0x40, 0xA0, 0x15AE, "E4FD300112E50EFFAE050DEE2403F582" },
+{ 0x40, 0xA0, 0x15BE, "E434E0F583EFF0E50FAE050D74032EF5" },
+{ 0x40, 0xA0, 0x15CE, "82E434E0F583E50FF0AF1C7AE07B0312" },
+{ 0x40, 0xA0, 0x15DE, "1720AF1CAD10AB12AA11121704" },
+{ 0x40, 0xA0, 0x15EB, "22" },
+{ 0x40, 0xA0, 0x166E, "C0E0C083C082C085C084C086758600D2" },
+{ 0x40, 0xA0, 0x167E, "005391EF907FAB7401F0D086D084D085" },
+{ 0x40, 0xA0, 0x168E, "D082D083D0E032" },
+{ 0x40, 0xA0, 0x1644, "C0E0C083C082C085C084C08675860090" },
+{ 0x40, 0xA0, 0x1654, "7FC4E4F05391EF907FAB7404F0D086D0" },
+{ 0x40, 0xA0, 0x1664, "84D085D082D083D0E032" },
+{ 0x40, 0xA0, 0x1695, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x16A5, "91EF907FAB7402F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x16B5, "D083D0E032" },
+{ 0x40, 0xA0, 0x16BA, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x16CA, "91EF907FAB7410F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x16DA, "D083D0E032" },
+{ 0x40, 0xA0, 0x14FF, "32" },
+{ 0x40, 0xA0, 0x16DF, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x16EF, "91EF907FAB7408F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x16FF, "D083D0E032" },
+{ 0x40, 0xA0, 0x1767, "32" },
+{ 0x40, 0xA0, 0x1768, "32" },
+{ 0x40, 0xA0, 0x1769, "32" },
+{ 0x40, 0xA0, 0x176A, "32" },
+{ 0x40, 0xA0, 0x176B, "32" },
+{ 0x40, 0xA0, 0x176C, "32" },
+{ 0x40, 0xA0, 0x176D, "32" },
+{ 0x40, 0xA0, 0x176E, "32" },
+{ 0x40, 0xA0, 0x176F, "32" },
+{ 0x40, 0xA0, 0x1770, "32" },
+{ 0x40, 0xA0, 0x1771, "32" },
+{ 0x40, 0xA0, 0x1772, "32" },
+{ 0x40, 0xA0, 0x1773, "32" },
+{ 0x40, 0xA0, 0x1774, "32" },
+{ 0x40, 0xA0, 0x1775, "32" },
+{ 0x40, 0xA0, 0x1776, "32" },
+{ 0x40, 0xA0, 0x0043, "021500" },
+{ 0x40, 0xA0, 0x1500, "02166E0002169500021644000216DF00" },
+{ 0x40, 0xA0, 0x1510, "0216BA000214FF000217670002176800" },
+{ 0x40, 0xA0, 0x1520, "0217690002176A0002176B0002176C00" },
+{ 0x40, 0xA0, 0x1530, "02176D0002176E0002176F0002177000" },
+{ 0x40, 0xA0, 0x1540, "02177100021772000217730002177400" },
+{ 0x40, 0xA0, 0x1550, "0217750002177600" },
+{ 0x40, 0xA0, 0x173C, "8E148F15E5151515AE14700215144E60" },
+{ 0x40, 0xA0, 0x174C, "051214EE80EE22" },
+{ 0x40, 0xA0, 0x175F, "E4F51BD2E9D2AF22" },
+{ 0x40, 0xA0, 0x1619, "A907E51B7023907FA5E04480F0E925E0" },
+{ 0x40, 0xA0, 0x1629, "907FA6F08D16AF03A9077517018A1889" },
+{ 0x40, 0xA0, 0x1639, "19E4F51A751B01D322C322" },
+{ 0x40, 0xA0, 0x15EC, "A907E51B7025907FA5E04480F0E925E0" },
+{ 0x40, 0xA0, 0x15FC, "4401907FA6F08D16AF03A9077517018A" },
+{ 0x40, 0xA0, 0x160C, "188919E4F51A751B03D322C322" },
+{ 0x40, 0xA0, 0x004B, "02137F" },
+{ 0x40, 0xA0, 0x137F, "C0E0C083C082C085C084C086758600C0" },
+{ 0x40, 0xA0, 0x138F, "D075D000C000C001C002C003C006C007" },
+{ 0x40, 0xA0, 0x139F, "907FA5E030E206751B0602144E907FA5" },
+{ 0x40, 0xA0, 0x13AF, "E020E10CE51B64026006751B0702144E" },
+{ 0x40, 0xA0, 0x13BF, "AF1BEF24FE604814602C24FE60772404" },
+{ 0x40, 0xA0, 0x13CF, "600302144EAB17AA18A919AF1A051A8F" },
+{ 0x40, 0xA0, 0x13DF, "8275830012124B907FA6F0E51A651670" },
+{ 0x40, 0xA0, 0x13EF, "5E751B058059907FA6E0AB17AA18A919" },
+{ 0x40, 0xA0, 0x13FF, "AE1A8E82758300121278751B028040E5" },
+{ 0x40, 0xA0, 0x140F, "1624FEB51A07907FA5E04420F0E51614" },
+{ 0x40, 0xA0, 0x141F, "B51A0A907FA5E04440F0751B00907FA6" },
+{ 0x40, 0xA0, 0x142F, "E0AB17AA18A919AE1A8E827583001212" },
+{ 0x40, 0xA0, 0x143F, "78051A800A907FA5E04440F0751B0053" },
+{ 0x40, 0xA0, 0x144F, "91DFD007D006D003D002D001D000D0D0" },
+{ 0x40, 0xA0, 0x145F, "D086D084D085D082D083D0E032" },
+{ 0x40, 0xA0, 0x1704, "1215ECE51B24FA600E146006240770F3" },
+{ 0x40, 0xA0, 0x1714, "D322E4F51BD322E4F51BD322" },
+{ 0x40, 0xA0, 0x1720, "121619E51B24FA600E146006240770F3" },
+{ 0x40, 0xA0, 0x1730, "D322E4F51BD322E4F51BD322" },
+{ 0x40, 0xA0, 0x14EE, "7400F58690FDA57C05A3E582458370F9" },
+{ 0x40, 0xA0, 0x14FE, "22" },
+{ 0x40, 0xA0, 0x0000, "021753" },
+{ 0x40, 0xA0, 0x1753, "787FE4F6D8FD75812002146C" },
+{ 0x40, 0xA0, 0x124B, "BB010CE58229F582E5833AF583E02250" },
+{ 0x40, 0xA0, 0x125B, "06E92582F8E622BBFE06E92582F8E222" },
+{ 0x40, 0xA0, 0x126B, "E58229F582E5833AF583E49322" },
+{ 0x40, 0xA0, 0x1278, "F8BB010DE58229F582E5833AF583E8F0" },
+{ 0x40, 0xA0, 0x1288, "225006E92582C8F622BBFE05E92582C8" },
+{ 0x40, 0xA0, 0x1298, "F222" },
+{ 0x40, 0xA0, 0x129A, "E709F608DFFA8046E709F208DFFA803E" },
+{ 0x40, 0xA0, 0x12AA, "88828C83E709F0A3DFFA8032E309F608" },
+{ 0x40, 0xA0, 0x12BA, "DFFA806EE309F208DFFA806688828C83" },
+{ 0x40, 0xA0, 0x12CA, "E309F0A3DFFA805A89828A83E0A3F608" },
+{ 0x40, 0xA0, 0x12DA, "DFFA804E89828A83E0A3F208DFFA8042" },
+{ 0x40, 0xA0, 0x12EA, "80D280FA80C680D4805580F280298010" },
+{ 0x40, 0xA0, 0x12FA, "80A680EA809A80A880DA80E280CA8029" },
+{ 0x40, 0xA0, 0x130A, "88848C8589828A83E493A30586F0A305" },
+{ 0x40, 0xA0, 0x131A, "86DFF5DEF3800B89828A83E493A3F608" },
+{ 0x40, 0xA0, 0x132A, "DFF9ECFAA9F0EDFB2288848C8589828A" },
+{ 0x40, 0xA0, 0x133A, "83E0A30586F0A30586DFF6DEF480E389" },
+{ 0x40, 0xA0, 0x134A, "828A83E493A3F208DFF980D688F0ED24" },
+{ 0x40, 0xA0, 0x135A, "02B4040050CCF582EB2402B4040050C2" },
+{ 0x40, 0xA0, 0x136A, "23234582F582EF4E60B8EF60010EE582" },
+{ 0x40, 0xA0, 0x137A, "239012EA73" },
+{ 0x40, 0xA0, 0x7F92, "00" },
+{ 0x40, 0xA0, 0x7F92, "01" },
+{ 0x40, 0xA0, 0x0100, "907FE9E0700302029B14700302031724" },
+{ 0x40, 0xA0, 0x0110, "FE700302038E24FB7003020295147003" },
+{ 0x40, 0xA0, 0x0120, "02028F14700302028314700302028924" },
+{ 0x40, 0xA0, 0x0130, "0560030203E2120F7A40030203EE907F" },
+{ 0x40, 0xA0, 0x0140, "EBE024FE601914604724026003020279" },
+{ 0x40, 0xA0, 0x0150, "E50C907FD4F0E50D907FD5F00203EE90" },
+{ 0x40, 0xA0, 0x0160, "7FEAE0FF121710AA06A9077B018B498A" },
+{ 0x40, 0xA0, 0x0170, "4A894BEA49600FEE907FD4F0AF01EF90" },
+{ 0x40, 0xA0, 0x0180, "7FD5F00203EE907FB4E04401F00203EE" },
+{ 0x40, 0xA0, 0x0190, "907FEAE0FF1216E4AA06A9077B018B49" },
+{ 0x40, 0xA0, 0x01A0, "8A4A894BEA49700302026F" },
+{ 0x40, 0xA0, 0x01AB, "AB498B508A5189521217F4F553907FEE" },
+{ 0x40, 0xA0, 0x01BB, "E0FFE553D39F4003E0F553E553700302" },
+{ 0x40, 0xA0, 0x01CB, "0261754F00754E00754D00754C00E553" },
+{ 0x40, 0xA0, 0x01DB, "C394405004AF5380027F40E4FCFDFEAB" },
+{ 0x40, 0xA0, 0x01EB, "4FAA4EA94DA84CC31218625038E55225" },
+{ 0x40, 0xA0, 0x01FB, "4FF582E54E3551F583E0FF7400254FF5" },
+{ 0x40, 0xA0, 0x020B, "82E4347FF583EFF07A0079007800E54F" },
+{ 0x40, 0xA0, 0x021B, "2401F54FEA354EF54EE9354DF54DE835" },
+{ 0x40, 0xA0, 0x022B, "4CF54C80A9E553C394405004AF538002" },
+{ 0x40, 0xA0, 0x023B, "7F40907FB5EFF0E553C394405004AF53" },
+{ 0x40, 0xA0, 0x024B, "80027F40C3E5539FF553907FB4E020E2" },
+{ 0x40, 0xA0, 0x025B, "030201C680F4E4907FB5F0907FB47402" },
+{ 0x40, 0xA0, 0x026B, "F0" },
+{ 0x40, 0xA0, 0x026C, "0203EE907FB4E04401F00203EE907FB4" },
+{ 0x40, 0xA0, 0x027C, "E04401F00203EE120FA60203EE120F9A" },
+{ 0x40, 0xA0, 0x028C, "0203EE120F7C0203EE120F880203EE12" },
+{ 0x40, 0xA0, 0x029C, "0FB840030203EE907FE8E0247F602414" },
+{ 0x40, 0xA0, 0x02AC, "60312402705BA200E433FF25E0FFA202" },
+{ 0x40, 0xA0, 0x02BC, "E4334F907F00F0E4A3F0907FB57402F0" },
+{ 0x40, 0xA0, 0x02CC, "0203EEE4907F00F0A3F0907FB57402F0" },
+{ 0x40, 0xA0, 0x02DC, "0203EE907FECE0F45480FFC4540FFFE0" },
+{ 0x40, 0xA0, 0x02EC, "54072F25E024B4F582E4347FF583E054" },
+{ 0x40, 0xA0, 0x02FC, "01907F00F0E4A3F0907FB57402F00203" },
+{ 0x40, 0xA0, 0x030C, "EE907FB4E04401F00203EE120FBA4003" },
+{ 0x40, 0xA0, 0x031C, "0203EE907FE8E024FE601D2402600302" },
+{ 0x40, 0xA0, 0x032C, "03EE907FEAE0B40105C2000203EE907F" },
+{ 0x40, 0xA0, 0x033C, "B4E04401F00203EE907FEAE0703B907F" },
+{ 0x40, 0xA0, 0x034C, "ECE0F45480FFC4540FFFE054072F25E0" },
+{ 0x40, 0xA0, 0x035C, "24B4F582E4347FF583E4F0907FECE054" },
+{ 0x40, 0xA0, 0x036C, "80FF131313541FFFE054072F907FD7F0" },
+{ 0x40, 0xA0, 0x037C, "E4F550" },
+{ 0x40, 0xA0, 0x037F, "E04420F08069907FB4E04401F0806012" },
+{ 0x40, 0xA0, 0x038F, "0FBC505B907FE8E024FE60182402704F" },
+{ 0x40, 0xA0, 0x039F, "907FEAE0B40104D2008044907FB4E044" },
+{ 0x40, 0xA0, 0x03AF, "01F0803B907FEAE07020907FECE0F454" },
+{ 0x40, 0xA0, 0x03BF, "80FFC4540FFFE054072F25E024B4F582" },
+{ 0x40, 0xA0, 0x03CF, "E4347FF5837401F08015907FB4E04401" },
+{ 0x40, 0xA0, 0x03DF, "F0800C120FBE5007907FB4E04401F090" },
+{ 0x40, 0xA0, 0x03EF, "7FB4E04402F0" },
+{ 0x40, 0xA0, 0x03F5, "22" },
+{ 0x40, 0xA0, 0x0033, "0203F6" },
+{ 0x40, 0xA0, 0x03F6, "53D8EF32" },
+{ 0x40, 0xA0, 0x000B, "0203FA" },
+{ 0x40, 0xA0, 0x03FA, "C0E0C0D0C000C001C002C004C005C006" },
+{ 0x40, 0xA0, 0x040A, "C007C28C758AD1758C63D28CAF0BAE0A" },
+{ 0x40, 0xA0, 0x041A, "AD09AC087A0079007800EF2401F50BEA" },
+{ 0x40, 0xA0, 0x042A, "3EF50AE93DF509E83CF508D007D006D0" },
+{ 0x40, 0xA0, 0x043A, "05D004D002D001D000D0D0D0E032" },
+{ 0x40, 0xA0, 0x0448, "750B00750A00750900750800C28C5389" },
+{ 0x40, 0xA0, 0x0458, "F0438901758AD1758C63C2B9D2A9D28C" },
+{ 0x40, 0xA0, 0x0468, "22" },
+{ 0x40, 0xA0, 0x0469, "754400754300754200754100C203C200" },
+{ 0x40, 0xA0, 0x0479, "C202C201120F037E067F228E0C8F0D75" },
+{ 0x40, 0xA0, 0x0489, "0E06750F347510067511A8EE54E07003" },
+{ 0x40, 0xA0, 0x0499, "0205897545007546808E478F48C374F6" },
+{ 0x40, 0xA0, 0x04A9, "9FFF74069ECF2402CF3400FEE48F408E" },
+{ 0x40, 0xA0, 0x04B9, "3FF53EF53DF53CF53BF53AF539AF40AE" },
+{ 0x40, 0xA0, 0x04C9, "3FAD3EAC3DAB3CAA3BA93AA839C31218" },
+{ 0x40, 0xA0, 0x04D9, "62502CE546253CF582E53B3545F58374" },
+{ 0x40, 0xA0, 0x04E9, "CDF07A0079007800E53C2401F53CEA35" },
+{ 0x40, 0xA0, 0x04F9, "3BF53BE9353AF53AE83539F53980BE75" },
+{ 0x40, 0xA0, 0x0509, "3C00753B00753A00753900AF40AE3FAD" },
+{ 0x40, 0xA0, 0x0519, "3EAC3DAB3CAA3BA93AA839C312186250" },
+{ 0x40, 0xA0, 0x0529, "39AE3BAF3CE5482FF582EE3547F583E0" },
+{ 0x40, 0xA0, 0x0539, "FDE5462FF582EE3545F583EDF07A0079" },
+{ 0x40, 0xA0, 0x0549, "007800E53C2401F53CEA353BF53BE935" },
+{ 0x40, 0xA0, 0x0559, "3AF53AE83539F53980B185450C85460D" },
+{ 0x40, 0xA0, 0x0569, "74222480FF740634FFFEC3E50F9FF50F" },
+{ 0x40, 0xA0, 0x0579, "E50E9EF50EC3E5119FF511E5109EF510" },
+{ 0x40, 0xA0, 0x0589, "C2AFD2E843D820120448907FAFE04401" },
+{ 0x40, 0xA0, 0x0599, "F0907FAEE0441DF0D2AFC2AAC2A82001" },
+{ 0x40, 0xA0, 0x05A9, "4A200105D20B12169375440075430075" },
+{ 0x40, 0xA0, 0x05B9, "42007541007F407E927D047C00AB44AA" },
+{ 0x40, 0xA0, 0x05C9, "43A942A841C312186250D32001D07A00" },
+{ 0x40, 0xA0, 0x05D9, "79007800E5442401F544EA3543F543E9" },
+{ 0x40, 0xA0, 0x05E9, "3542F542E83541F54180CA538EF83001" },
+{ 0x40, 0xA0, 0x05F9, "05120100C20130031A120F705015C203" },
+{ 0x40, 0xA0, 0x0609, "121672200007907FD6E020E7F3121658" },
+{ 0x40, 0xA0, 0x0619, "120F75120F4C80D6" },
+{ 0x40, 0xA0, 0x0621, "22" },
+{ 0x40, 0xA0, 0x0622, "12010001FFFFFF40D804018003000000" },
+{ 0x40, 0xA0, 0x0632, "000109027400010100804B090400000E" },
+{ 0x40, 0xA0, 0x0642, "FFFFFF00070501024000010705020240" },
+{ 0x40, 0xA0, 0x0652, "00010705030240000107050402400001" },
+{ 0x40, 0xA0, 0x0662, "07050502400001070506024000010705" },
+{ 0x40, 0xA0, 0x0672, "07024000010705810240000107058202" },
+{ 0x40, 0xA0, 0x0682, "40000107058302400001070584024000" },
+{ 0x40, 0xA0, 0x0692, "01070585024000010705860240000107" },
+{ 0x40, 0xA0, 0x06A2, "058702400001040309042A034D006900" },
+{ 0x40, 0xA0, 0x06B2, "630072006F0063006800690070002000" },
+{ 0x40, 0xA0, 0x06C2, "54006500630068006E006F006C006F00" },
+{ 0x40, 0xA0, 0x06D2, "67007900200349004300440032002000" },
+{ 0x40, 0xA0, 0x06E2, "55005300420020004400650076006900" },
+{ 0x40, 0xA0, 0x06F2, "630065000000" },
+{ 0x40, 0xA0, 0x1289, "436F7079726967687420284329203230" },
+{ 0x40, 0xA0, 0x1299, "3032204D6963726F6368697020546563" },
+{ 0x40, 0xA0, 0x12A9, "686E6F6C6F67792C20496E632E000000" },
+{ 0x40, 0xA0, 0x12B9, "00004672616D65776F726B7320636F70" },
+{ 0x40, 0xA0, 0x12C9, "79726967687420284329203139393820" },
+{ 0x40, 0xA0, 0x12D9, "416E63686F722043686970732C20496E" },
+{ 0x40, 0xA0, 0x12E9, "632E0000" },
+{ 0x40, 0xA0, 0x11B5, "60C01A50FF13CBFF1507FF15DD000000" },
+{ 0x40, 0xA0, 0x11C5, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x11D5, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x11E5, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x11F5, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1205, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1215, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1225, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1235, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1245, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1255, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1265, "00000000000000000000000000000000" },
+{ 0x40, 0xA0, 0x1275, "00000000421B120000421B150000421B" },
+{ 0x40, 0xA0, 0x1285, "100000" },
+{ 0x40, 0xA0, 0x06F8, "8B128A138914751700751800AB12AA13" },
+{ 0x40, 0xA0, 0x0708, "A9141217F4FF7E008E158F16C3E51694" },
+{ 0x40, 0xA0, 0x0718, "40E515648094805063AE15AF16901A50" },
+{ 0x40, 0xA0, 0x0728, "75F003EF1218C3EE75F003A42583F583" },
+{ 0x40, 0xA0, 0x0738, "E0FBA3E0FAA3E0F9EA496040AB12AA13" },
+{ 0x40, 0xA0, 0x0748, "A914C003C002C001AE15AF16901A5075" },
+{ 0x40, 0xA0, 0x0758, "F003EF1218C3EE75F003A42583F583E0" },
+{ 0x40, 0xA0, 0x0768, "FBA3E0FAA3E0F989828A83D001D002D0" },
+{ 0x40, 0xA0, 0x0778, "0312077E8002E4738E178F18AE17AF18" },
+{ 0x40, 0xA0, 0x0788, "22" },
+{ 0x40, 0xA0, 0x0789, "C2AFAF0BAE0AAD09AC088F1C8E1B8D1A" },
+{ 0x40, 0xA0, 0x0799, "8C19D2AFAF1CAE1BAD1AAC1922" },
+{ 0x40, 0xA0, 0x07A6, "907FC7E4F022" },
+{ 0x40, 0xA0, 0x07AC, "8E228F23901B10E0FEA3E0FF8E248F25" },
+{ 0x40, 0xA0, 0x07BC, "901B10E522F0A3E523F0AE24AF2522" },
+{ 0x40, 0xA0, 0x07CB, "901B10E0FEA3E0FF22" },
+{ 0x40, 0xA0, 0x07D4, "901A00EBF0A3EAF0A3E9F0901A031218" },
+{ 0x40, 0xA0, 0x07E4, "86901B12E4F0A37402F0901A09E0FEA3" },
+{ 0x40, 0xA0, 0x07F4, "E0FFEF30E018901A00E0FBA3E0FAA3E0" },
+{ 0x40, 0xA0, 0x0804, "F9901A1AEBF0A3EAF0A3E9F08016901A" },
+{ 0x40, 0xA0, 0x0814, "00E0FBA3E0FAA3E0F9901A13EBF0A3EA" },
+{ 0x40, 0xA0, 0x0824, "F0A3E9F0901A1DE4F0A37401F0901A09" },
+{ 0x40, 0xA0, 0x0834, "E0FEA3E0FFEEFF7E00901A17EFF0901A" },
+{ 0x40, 0xA0, 0x0844, "03E0FCA3E0FDA3E0FEA3E0FF901A0F12" },
+{ 0x40, 0xA0, 0x0854, "18867F007E007D007C00901A0FE0F8A3" },
+{ 0x40, 0xA0, 0x0864, "E0F9A3E0FAA3E0FBD31218625003020A" },
+{ 0x40, 0xA0, 0x0874, "72120D3C901A18EEF0FEA3EFF0FFEF4E" },
+{ 0x40, 0xA0, 0x0884, "7040901B10E0FEA3E0FFEF4E60E3901A" },
+{ 0x40, 0xA0, 0x0894, "03E0FCA3E0FDA3E0FEA3E0FF901A0FE0" },
+{ 0x40, 0xA0, 0x08A4, "F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE9A" },
+{ 0x40, 0xA0, 0x08B4, "FEED99FDEC98FC901A03121886020A72" },
+{ 0x40, 0xA0, 0x08C4, "80AF901A18E0FE" },
+{ 0x40, 0xA0, 0x08CB, "A3E0FFE4FCFD901A0B121886907FE374" },
+{ 0x40, 0xA0, 0x08DB, "7EF0907FE47440F0901A09E0FEA3E0FF" },
+{ 0x40, 0xA0, 0x08EB, "EF20E0030209E2907FE5E0FF901A16EF" },
+{ 0x40, 0xA0, 0x08FB, "F0901A1DE0FEA3E0FFEF64014E600302" },
+{ 0x40, 0xA0, 0x090B, "09BE7B017A1A7916C003C002C001901A" },
+{ 0x40, 0xA0, 0x091B, "1AE0FBA3E0FAA3E0F989828A83D001D0" },
+{ 0x40, 0xA0, 0x092B, "02D0031209338002E473EF4E70030209" },
+{ 0x40, 0xA0, 0x093B, "BE901A03E0FCA3E0FDA3E0FEA3E0FFC0" },
+{ 0x40, 0xA0, 0x094B, "04C005C006C007901A18E0FEA3E0FFE4" },
+{ 0x40, 0xA0, 0x095B, "FCFDA804A905AA06AB07901A0BE0FCA3" },
+{ 0x40, 0xA0, 0x096B, "E0FDA3E0FEA3E0FFC3EF9BFBEE9AFAED" },
+{ 0x40, 0xA0, 0x097B, "99F9EC98F8901A0FE0FCA3E0FDA3E0FE" },
+{ 0x40, 0xA0, 0x098B, "A3E0FFC3EF9BFBEE9AFAED99F9EC98F8" },
+{ 0x40, 0xA0, 0x099B, "D007D006D005D004C3EF9BFFEE9AFEED" },
+{ 0x40, 0xA0, 0x09AB, "99FDEC98FC901A03121886901A1DE4F0" },
+{ 0x40, 0xA0, 0x09BB, "A3E4F0901A19E024FFF0901A18E034FF" },
+{ 0x40, 0xA0, 0x09CB, "F0" },
+{ 0x40, 0xA0, 0x09CC, "901A18E0FEA3E0FFD3EF9400EE940040" },
+{ 0x40, 0xA0, 0x09DC, "030208F28044907FE5E0FF901A13E0FB" },
+{ 0x40, 0xA0, 0x09EC, "A3E0FAA3E0F9EF12183A901A07E0FEA3" },
+{ 0x40, 0xA0, 0x09FC, "E0FF901A14EE8FF012184C901A19E024" },
+{ 0x40, 0xA0, 0x0A0C, "FFF0901A18E034FFF0901A18E0FEA3E0" },
+{ 0x40, 0xA0, 0x0A1C, "FFD3EF9400EE940050BC901A0FE0FCA3" },
+{ 0x40, 0xA0, 0x0A2C, "E0FDA3E0FEA3E0FF901A0BE0F8A3E0F9" },
+{ 0x40, 0xA0, 0x0A3C, "A3E0FAA3E0FBC3EF9BFFEE9AFEED99FD" },
+{ 0x40, 0xA0, 0x0A4C, "EC98FC901A0F121886901A0FE0FCA3E0" },
+{ 0x40, 0xA0, 0x0A5C, "FDA3E0FEA3E0FFEC4D4E4F7003020856" },
+{ 0x40, 0xA0, 0x0A6C, "1207A6020856901A03E0FCA3E0FDA3E0" },
+{ 0x40, 0xA0, 0x0A7C, "FEA3E0FF22" },
+{ 0x40, 0xA0, 0x0A81, "901A1FEBF0A3EAF0A3E9F0901A221218" },
+{ 0x40, 0xA0, 0x0A91, "86901B12E4F0A37401F0901A28E0FEA3" },
+{ 0x40, 0xA0, 0x0AA1, "E0FFEF30E018901A1FE0FBA3E0FAA3E0" },
+{ 0x40, 0xA0, 0x0AB1, "F9901A38EBF0A3EAF0A3E9F08016901A" },
+{ 0x40, 0xA0, 0x0AC1, "1FE0FBA3E0FAA3E0F9901A35EBF0A3EA" },
+{ 0x40, 0xA0, 0x0AD1, "F0A3E9F0901A28E0FEA3E0FFEEFF7E00" },
+{ 0x40, 0xA0, 0x0AE1, "901A34EFF0901A22E0FCA3E0FDA3E0FE" },
+{ 0x40, 0xA0, 0x0AF1, "A3E0FF901A2E1218867F007E007D007C" },
+{ 0x40, 0xA0, 0x0B01, "00901A2EE0F8A3E0F9A3E0FAA3E0FBD3" },
+{ 0x40, 0xA0, 0x0B11, "1218625003020D2D7F407E007D007C00" },
+{ 0x40, 0xA0, 0x0B21, "901A2EE0F8A3E0F9A3E0FAA3E0FBD312" },
+{ 0x40, 0xA0, 0x0B31, "1862400C901A2A121892000000408014" },
+{ 0x40, 0xA0, 0x0B41, "901A2EE0FCA3E0FDA3E0FEA3E0FF901A" },
+{ 0x40, 0xA0, 0x0B51, "2A121886901A2DE0FF901A32EFF0907F" },
+{ 0x40, 0xA0, 0x0B61, "B8E0FFEF30E140901B10E0FEA3E0FFEF" },
+{ 0x40, 0xA0, 0x0B71, "4E60EB901A22E0FCA3E0FDA3E0FEA3E0" },
+{ 0x40, 0xA0, 0x0B81, "FF901A2EE0F8" },
+{ 0x40, 0xA0, 0x0B87, "A3E0F9A3E0FAA3E0FBC3EF9BFFEE9AFE" },
+{ 0x40, 0xA0, 0x0B97, "ED99FDEC98FC901A22121886020D2D80" },
+{ 0x40, 0xA0, 0x0BA7, "B7907FE3747EF0907FE4E4F0901A28E0" },
+{ 0x40, 0xA0, 0x0BB7, "FEA3E0FFEF20E003020CBB7B017A1A79" },
+{ 0x40, 0xA0, 0x0BC7, "33C003C002C001901A38E0FBA3E0FAA3" },
+{ 0x40, 0xA0, 0x0BD7, "E0F989828A83D001D002D003120BE880" },
+{ 0x40, 0xA0, 0x0BE7, "02E473901A3BEEF0FEA3EFF0FFEF4E70" },
+{ 0x40, 0xA0, 0x0BF7, "03020C9B901A3BE0FEA3E0FFEF64024E" },
+{ 0x40, 0xA0, 0x0C07, "7017901A32E0FFE4FCFDFE901A2DE0FE" },
+{ 0x40, 0xA0, 0x0C17, "C3EE9FFF907FB9EFF0901A22E0FCA3E0" },
+{ 0x40, 0xA0, 0x0C27, "FDA3E0FEA3E0FFC004C005C006C00790" },
+{ 0x40, 0xA0, 0x0C37, "1A32E0FFE4FCFDFEA804A905AA06AB07" },
+{ 0x40, 0xA0, 0x0C47, "901A2AE0FCA3E0FDA3E0FEA3E0FFC3EF" },
+{ 0x40, 0xA0, 0x0C57, "9BFBEE9AFAED99F9EC98F8901A2EE0FC" },
+{ 0x40, 0xA0, 0x0C67, "A3E0FDA3E0FEA3E0FFC3EF9BFBEE9AFA" },
+{ 0x40, 0xA0, 0x0C77, "ED99F9EC98" },
+{ 0x40, 0xA0, 0x0C7C, "F8D007D006D005D004C3EF9BFFEE9AFE" },
+{ 0x40, 0xA0, 0x0C8C, "ED99FDEC98FC901A22121886020D2D90" },
+{ 0x40, 0xA0, 0x0C9C, "1A33E0FF907FE5EFF0901A32E014F090" },
+{ 0x40, 0xA0, 0x0CAC, "1A32E0FFEFD394004003020BC2803690" },
+{ 0x40, 0xA0, 0x0CBC, "1A35E0FBA3E0FAA3E0F91217F4FF907F" },
+{ 0x40, 0xA0, 0x0CCC, "E5EFF0901A26E0FEA3E0FF901A36EE8F" },
+{ 0x40, 0xA0, 0x0CDC, "F012184C901A32E014F0901A32E0FFEF" },
+{ 0x40, 0xA0, 0x0CEC, "D3940050CA901A2DE0FF907FB9EFF090" },
+{ 0x40, 0xA0, 0x0CFC, "1A2EE0FCA3E0FDA3E0FEA3E0FF901A2A" },
+{ 0x40, 0xA0, 0x0D0C, "E0F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE" },
+{ 0x40, 0xA0, 0x0D1C, "9AFEED99FDEC98FC901A2E121886020A" },
+{ 0x40, 0xA0, 0x0D2C, "FA901A22E0FCA3E0FDA3E0FEA3E0FF22" },
+{ 0x40, 0xA0, 0x0D3C, "C2AF901B15E0FEA3E0FF8E1D8F1E901B" },
+{ 0x40, 0xA0, 0x0D4C, "15E4F0A3E4F0D2AFAE1DAF1E22" },
+{ 0x40, 0xA0, 0x0D59, "8B268A278928901B12E4F0A37404F0C2" },
+{ 0x40, 0xA0, 0x0D69, "04907FB6E0FFEF30E111901B10E0FEA3" },
+{ 0x40, 0xA0, 0x0D79, "E0FFEF4E60EB020E5680E6901A3EE0FF" },
+{ 0x40, 0xA0, 0x0D89, "907E80EFF0907E81E4F0AB26AA27A928" },
+{ 0x40, 0xA0, 0x0D99, "EA49607AAB26AA27A9281217F4FF907E" },
+{ 0x40, 0xA0, 0x0DA9, "82EFF0AB26AA27A92875820175830012" },
+{ 0x40, 0xA0, 0x0DB9, "180DFF907E83EFF0AB26AA27A9287582" },
+{ 0x40, 0xA0, 0x0DC9, "0275830012180DFF907E84EFF0AB26AA" },
+{ 0x40, 0xA0, 0x0DD9, "27A92875820375830012180DFF907E85" },
+{ 0x40, 0xA0, 0x0DE9, "EFF0AB26AA27A9287582047583001218" },
+{ 0x40, 0xA0, 0x0DF9, "0DFF907E86EFF0AB26AA27A928758205" },
+{ 0x40, 0xA0, 0x0E09, "75830012180DFF907E87EFF0801E907E" },
+{ 0x40, 0xA0, 0x0E19, "82E4F0907E83E4F0907E84E4F0907E85" },
+{ 0x40, 0xA0, 0x0E29, "E4F0907E86E4F0907E87E4F0907FB774" },
+{ 0x40, 0xA0, 0x0E39, "08F0907FB6E0FFEF30E110901B10E0FE" },
+{ 0x40, 0xA0, 0x0E49, "A3E0FFEF4E60EB800480E7D204901B12" },
+{ 0x40, 0xA0, 0x0E59, "E4F0A3E4F0A20422" },
+{ 0x40, 0xA0, 0x0E61, "A2009206A2059200A20622" },
+{ 0x40, 0xA0, 0x0E6C, "A2029208A2079202A20822" },
+{ 0x40, 0xA0, 0x0E77, "A203920AA2099203A20A22" },
+{ 0x40, 0xA0, 0x0E82, "901B12E0FEA3E0FF8E298F2A901B12E4" },
+{ 0x40, 0xA0, 0x0E92, "F0A3E4F0AE29AF2A22" },
+{ 0x40, 0xA0, 0x0E9B, "901B12E0FEA3E0FF8E2B8F2C901B12E4" },
+{ 0x40, 0xA0, 0x0EAB, "F0A37401F0AE2BAF2C22" },
+{ 0x40, 0xA0, 0x0EB5, "901B12E0FEA3E0FF8E2D8F2E901B12E4" },
+{ 0x40, 0xA0, 0x0EC5, "F0A37402F0AE2DAF2E22" },
+{ 0x40, 0xA0, 0x0ECF, "901B12E0FEA3E0FF8E2F8F30901B12E4" },
+{ 0x40, 0xA0, 0x0EDF, "F0A37403F0AE2FAF3022" },
+{ 0x40, 0xA0, 0x0EE9, "901B12E0FEA3E0FF8E318F32901B12E4" },
+{ 0x40, 0xA0, 0x0EF9, "F0A37404F0AE31AF3222" },
+{ 0x40, 0xA0, 0x0F03, "907FDFE0FFEF4402FF907FDFEFF0907F" },
+{ 0x40, 0xA0, 0x0F13, "DEE0FFEF4406FF907FDEEFF0907FAD74" },
+{ 0x40, 0xA0, 0x0F23, "02F0901B147401F0901A4FE4F0C203C2" },
+{ 0x40, 0xA0, 0x0F33, "00C2029078497401F0907FDD7401F090" },
+{ 0x40, 0xA0, 0x0F43, "7FE27440F01212ED22" },
+{ 0x40, 0xA0, 0x0F4C, "901B12E0FEA3E0FFEF64034E70157B01" },
+{ 0x40, 0xA0, 0x0F5C, "7A1A793D1206F8EF4E7008901B12E4F0" },
+{ 0x40, 0xA0, 0x0F6C, "A3E4F022" },
+{ 0x40, 0xA0, 0x0F70, "121339D322" },
+{ 0x40, 0xA0, 0x0F75, "12133BD322" },
+{ 0x40, 0xA0, 0x0F7A, "D322" },
+{ 0x40, 0xA0, 0x0F7C, "907FEAE0FF901B14EFF0D322" },
+{ 0x40, 0xA0, 0x0F88, "901B14E0FF907F00EFF0907FB57401F0" },
+{ 0x40, 0xA0, 0x0F98, "D322" },
+{ 0x40, 0xA0, 0x0F9A, "907FEAE0FF901A4FEFF0D322" },
+{ 0x40, 0xA0, 0x0FA6, "901A4FE0FF907F00EFF0907FB57401F0" },
+{ 0x40, 0xA0, 0x0FB6, "D322" },
+{ 0x40, 0xA0, 0x0FB8, "D322" },
+{ 0x40, 0xA0, 0x0FBA, "D322" },
+{ 0x40, 0xA0, 0x0FBC, "D322" },
+{ 0x40, 0xA0, 0x0FBE, "D322" },
+{ 0x40, 0xA0, 0x0FC0, "C0E0C083C082C085C084C086758600D2" },
+{ 0x40, 0xA0, 0x0FD0, "015391EF907FAB7401F0D086D084D085" },
+{ 0x40, 0xA0, 0x0FE0, "D082D083D0E032" },
+{ 0x40, 0xA0, 0x0FE7, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x0FF7, "91EF907FAB7404F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x1007, "D083D0E032" },
+{ 0x40, 0xA0, 0x100C, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x101C, "91EF907FAB7402F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x102C, "D083D0E032" },
+{ 0x40, 0xA0, 0x1031, "C0E0C083C082C085C084C08675860090" },
+{ 0x40, 0xA0, 0x1041, "7FC7E4F0907FC9E4F0907FCBE4F0907F" },
+{ 0x40, 0xA0, 0x1051, "CDE4F0907FCFE4F0907FD1E4F0907FD3" },
+{ 0x40, 0xA0, 0x1061, "E4F05391EF907FAB7410F0D086D084D0" },
+{ 0x40, 0xA0, 0x1071, "85D082D083D0E032" },
+{ 0x40, 0xA0, 0x1079, "C0E0C083C082C085C084C08675860053" },
+{ 0x40, 0xA0, 0x1089, "91EF907FAB7420F0D086D084D085D082" },
+{ 0x40, 0xA0, 0x1099, "D083D0E032" },
+{ 0x40, 0xA0, 0x109E, "C0E0C083C082C085C084C086758600D2" },
+{ 0x40, 0xA0, 0x10AE, "035391EF907FAB7408F0D086D084D085" },
+{ 0x40, 0xA0, 0x10BE, "D082D083D0E032" },
+{ 0x40, 0xA0, 0x10C5, "32" },
+{ 0x40, 0xA0, 0x10C6, "32" },
+{ 0x40, 0xA0, 0x10C7, "32" },
+{ 0x40, 0xA0, 0x10C8, "C0E0C0F0C083C082C085C084C0867586" },
+{ 0x40, 0xA0, 0x10D8, "00C0D0C000C001C002C003C004C005C0" },
+{ 0x40, 0xA0, 0x10E8, "06C007901B12E0FEA3E0FFEF8EF01218" },
+{ 0x40, 0xA0, 0x10F8, "CF11240000117C000111110002117C00" },
+{ 0x40, 0xA0, 0x1108, "03117C00040000117C907FC7E0FF7E00" },
+{ 0x40, 0xA0, 0x1118, "901B15EEF0A3EFF0805D8058907E40E0" },
+{ 0x40, 0xA0, 0x1128, "FFEFB44011907E42E0FF7E00901B10EE" },
+{ 0x40, 0xA0, 0x1138, "F0A3EFF0803E753300753400C3E53494" },
+{ 0x40, 0xA0, 0x1148, "12E533648094805026AF3474402FF582" },
+{ 0x40, 0xA0, 0x1158, "E4347EF583E0FFAE34743D2EF582E434" },
+{ 0x40, 0xA0, 0x1168, "1AF583EFF00534E5347002053380CD12" },
+{ 0x40, 0xA0, 0x1178, "0ECF80031207A65391EF907FAA7402F0" },
+{ 0x40, 0xA0, 0x1188, "D007D006D005D004D003D002D001D000" },
+{ 0x40, 0xA0, 0x1198, "D0D0D086D084D085D082D083D0F0D0E0" },
+{ 0x40, 0xA0, 0x11A8, "32" },
+{ 0x40, 0xA0, 0x11A9, "32" },
+{ 0x40, 0xA0, 0x11AA, "32" },
+{ 0x40, 0xA0, 0x11AB, "32" },
+{ 0x40, 0xA0, 0x11AC, "32" },
+{ 0x40, 0xA0, 0x11AD, "32" },
+{ 0x40, 0xA0, 0x11AE, "32" },
+{ 0x40, 0xA0, 0x11AF, "32" },
+{ 0x40, 0xA0, 0x11B0, "32" },
+{ 0x40, 0xA0, 0x11B1, "32" },
+{ 0x40, 0xA0, 0x11B2, "32" },
+{ 0x40, 0xA0, 0x11B3, "32" },
+{ 0x40, 0xA0, 0x11B4, "32" },
+{ 0x40, 0xA0, 0x12ED, "90784A7480F0C207120E6CC205120E61" },
+{ 0x40, 0xA0, 0x12FD, "907F9D74FFF0907F977447F0E4907F95" },
+{ 0x40, 0xA0, 0x130D, "F0907F9E74FBF0E4907F93F0907F9C74" },
+{ 0x40, 0xA0, 0x131D, "FFF0D2A0E4FFFE0FBF00010EBE92F8BF" },
+{ 0x40, 0xA0, 0x132D, "48F5C2A0D2A5D2A6D2A7D322" },
+{ 0x40, 0xA0, 0x1339, "D322" },
+{ 0x40, 0xA0, 0x133B, "D322" },
+{ 0x40, 0xA0, 0x133D, "8B498A4A894BE4F54CF54D1207898F51" },
+{ 0x40, 0xA0, 0x134D, "8E508D4F8C4E120789C3EF9551FFEE95" },
+{ 0x40, 0xA0, 0x135D, "50FEED954FFDEC954EFCAB38AA37A936" },
+{ 0x40, 0xA0, 0x136D, "A835C31218625008754C00754D028049" },
+{ 0x40, 0xA0, 0x137D, "30A2D3E4907F9DF0C2A5C2A7D2A7AB49" },
+{ 0x40, 0xA0, 0x138D, "AA4AA94B90000112180D30E717907F9A" },
+{ 0x40, 0xA0, 0x139D, "E0F552E92401F9E43AFA1217F4547F12" },
+{ 0x40, 0xA0, 0x13AD, "183A8097907F9AE0AB49AA4AA94B1218" },
+{ 0x40, 0xA0, 0x13BD, "3AD2A5907F9D74FFF0AE4CAF4D22" },
+{ 0x40, 0xA0, 0x13CB, "E4F54390000D12180DF53990000C1218" },
+{ 0x40, 0xA0, 0x13DB, "0DF53A90000B12180DF53B90000A1218" },
+{ 0x40, 0xA0, 0x13EB, "0DF53CAF3CAE3BAD3AAC398F388E378D" },
+{ 0x40, 0xA0, 0x13FB, "368C3590000512180DF5399000041218" },
+{ 0x40, 0xA0, 0x140B, "0DF53A90000312180DF53B9000021218" },
+{ 0x40, 0xA0, 0x141B, "0DF53C120E9B1207A6753D00753E017B" },
+{ 0x40, 0xA0, 0x142B, "FF7A13793DAF3CAE3BAD3AAC39E4901A" },
+{ 0x40, 0xA0, 0x143B, "26F0A3F0A3E53DF0A3E53EF0120A818F" },
+{ 0x40, 0xA0, 0x144B, "428E418D408C3FAB3CAA3BA93AA839C3" },
+{ 0x40, 0xA0, 0x145B, "1218626036754302854244AF42AE41AD" },
+{ 0x40, 0xA0, 0x146B, "40AC3F78081218738F45AF42AE41AD40" },
+{ 0x40, 0xA0, 0x147B, "AC3F78101218738F46AF42AE41AD40AC" },
+{ 0x40, 0xA0, 0x148B, "3F78181218738F47E4F5487B007A0079" },
+{ 0x40, 0xA0, 0x149B, "43120D59120E821207A67E007F0122" },
+{ 0x40, 0xA0, 0x14AA, "8B478A488949E4F54AF54B1207898F4F" },
+{ 0x40, 0xA0, 0x14BA, "8E4E8D4D8C4C120789C3EF954FFFEE95" },
+{ 0x40, 0xA0, 0x14CA, "4EFEED954DFDEC954CFCAB38AA37A936" },
+{ 0x40, 0xA0, 0x14DA, "A835C31218625008754A00754B018018" },
+{ 0x40, 0xA0, 0x14EA, "30A2D3C2A5C2A6AB47AA48A9491217F4" },
+{ 0x40, 0xA0, 0x14FA, "907F97F0D2A6D2A5AE4AAF4B22" },
+{ 0x40, 0xA0, 0x1507, "E4F53D90000D12180DF53990000C1218" },
+{ 0x40, 0xA0, 0x1517, "0DF53A90000B12180DF53B90000A1218" },
+{ 0x40, 0xA0, 0x1527, "0DF53CAF3CAE3BAD3AAC398F388E378D" },
+{ 0x40, 0xA0, 0x1537, "368C3590000512180DF5399000041218" },
+{ 0x40, 0xA0, 0x1547, "0DF53A90000312180DF53B9000021218" },
+{ 0x40, 0xA0, 0x1557, "0DF53C120EB51207A67BFF7A1479AAAF" },
+{ 0x40, 0xA0, 0x1567, "3CAE3BAD3AAC39E4901A07F0A3F0A3F0" },
+{ 0x40, 0xA0, 0x1577, "A304F01207D48F468E458D448C43AB3C" },
+{ 0x40, 0xA0, 0x1587, "AA3BA93AA839C31218626036753D0185" },
+{ 0x40, 0xA0, 0x1597, "463EAF46AE45AD44AC4378081218738F" },
+{ 0x40, 0xA0, 0x15A7, "3FAF46AE45AD44AC4378101218738F40" },
+{ 0x40, 0xA0, 0x15B7, "AF46AE45AD44AC4378181218738F41E4" },
+{ 0x40, 0xA0, 0x15C7, "F5427B007A00793D120D59120E821207" },
+{ 0x40, 0xA0, 0x15D7, "A67E007F0122" },
+{ 0x40, 0xA0, 0x15DD, "8B398A3A893B1212EDE4F53CFB7A0079" },
+{ 0x40, 0xA0, 0x15ED, "3C120D59120E821207A67E007F0122" },
+{ 0x40, 0xA0, 0x0043, "021600" },
+{ 0x40, 0xA0, 0x1600, "020FC00002100C00020FE70002109E00" },
+{ 0x40, 0xA0, 0x1610, "02103100021079000210C5000210C600" },
+{ 0x40, 0xA0, 0x1620, "0210C7000210C8000211A9000211AA00" },
+{ 0x40, 0xA0, 0x1630, "0211AB000211AC000211AD000211AE00" },
+{ 0x40, 0xA0, 0x1640, "0211AF000211B0000211B1000211B200" },
+{ 0x40, 0xA0, 0x1650, "0211B3000211B400" },
+{ 0x40, 0xA0, 0x1658, "907FD6E030E712E04401F07F147E0012" },
+{ 0x40, 0xA0, 0x1668, "1751907FD6E054FEF022" },
+{ 0x40, 0xA0, 0x1672, "907FD6E04480F0438701000000000022" },
+{ 0x40, 0xA0, 0x1693, "907FD6E04408F0" },
+{ 0x40, 0xA0, 0x169A, "E4F549" },
+{ 0x40, 0xA0, 0x169D, "E054FBF0" },
+{ 0x40, 0xA0, 0x16A1, "E4F549" },
+{ 0x40, 0xA0, 0x16A4, "E04408F0300B04E04402F07FDC7E0512" },
+{ 0x40, 0xA0, 0x16B4, "1751907F92E030E3077FDC7E05121751" },
+{ 0x40, 0xA0, 0x16C4, "907FAB74FFF0907FA9F0907FAAF05391" },
+{ 0x40, 0xA0, 0x16D4, "EF907FD6E054F7F0" },
+{ 0x40, 0xA0, 0x16DC, "E4F549" },
+{ 0x40, 0xA0, 0x16DF, "E04404F022" },
+{ 0x40, 0xA0, 0x16E4, "A907" },
+{ 0x40, 0xA0, 0x16E6, "AE10AF118F828E83A3E064037017AD01" },
+{ 0x40, 0xA0, 0x16F6, "19ED7001228F828E83E07C002FFDEC3E" },
+{ 0x40, 0xA0, 0x1706, "FEAF0580DF7E007F00" },
+{ 0x40, 0xA0, 0x170F, "22" },
+{ 0x40, 0xA0, 0x1710, "AD07" },
+{ 0x40, 0xA0, 0x1712, "E4FCAE0EAF0F8F828E83A3E06402702A" },
+{ 0x40, 0xA0, 0x1722, "AB040CEBB50501228F828E83A3A3E0FA" },
+{ 0x40, 0xA0, 0x1732, "A3E08A54F5556254E5546255E5556254" },
+{ 0x40, 0xA0, 0x1742, "2FFBE5543EFEAF0380CC7E007F00" },
+{ 0x40, 0xA0, 0x1750, "22" },
+{ 0x40, 0xA0, 0x1751, "8E4A8F4BE54B154BAE4A7002154A4E60" },
+{ 0x40, 0xA0, 0x1761, "0512168280EE22" },
+{ 0x40, 0xA0, 0x1682, "7400F58690FDA57C05A3E582458370F9" },
+{ 0x40, 0xA0, 0x1692, "22" },
+{ 0x40, 0xA0, 0x0000, "021768" },
+{ 0x40, 0xA0, 0x1768, "787FE4F6D8FD7581550217AF" },
+{ 0x40, 0xA0, 0x17F4, "BB010689828A83E0225002E722BBFE02" },
+{ 0x40, 0xA0, 0x1804, "E32289828A83E49322" },
+{ 0x40, 0xA0, 0x180D, "BB010CE58229F582E5833AF583E02250" },
+{ 0x40, 0xA0, 0x181D, "06E92582F8E622BBFE06E92582F8E222" },
+{ 0x40, 0xA0, 0x182D, "E58229F582E5833AF583E49322" },
+{ 0x40, 0xA0, 0x183A, "BB010689828A83F0225002F722BBFE01" },
+{ 0x40, 0xA0, 0x184A, "F322" },
+{ 0x40, 0xA0, 0x184C, "C5F0F8A3E028F0C5F0F8E58215827002" },
+{ 0x40, 0xA0, 0x185C, "1583E038F022" },
+{ 0x40, 0xA0, 0x1862, "EB9FF5F0EA9E42F0E99D42F0E89C45F0" },
+{ 0x40, 0xA0, 0x1872, "22" },
+{ 0x40, 0xA0, 0x1873, "E8600FECC313FCED13FDEE13FEEF13FF" },
+{ 0x40, 0xA0, 0x1883, "D8F122" },
+{ 0x40, 0xA0, 0x1886, "ECF0A3EDF0A3EEF0A3EFF022" },
+{ 0x40, 0xA0, 0x1892, "A8828583F0D083D0821218A91218A912" },
+{ 0x40, 0xA0, 0x18A2, "18A91218A9E473E493A3C583C5F0C583" },
+{ 0x40, 0xA0, 0x18B2, "C8C582C8F0A3C583C5F0C583C8C582C8" },
+{ 0x40, 0xA0, 0x18C2, "22" },
+{ 0x40, 0xA0, 0x18C3, "A42582F582E5F03583F58322" },
+{ 0x40, 0xA0, 0x18CF, "D083D082F8E4937012740193700DA3A3" },
+{ 0x40, 0xA0, 0x18DF, "93F8740193F5828883E473740293B5F0" },
+{ 0x40, 0xA0, 0x18EF, "067403936860E9A3A3A3A380D8" },
+{ 0x40, 0xA0, 0x1774, "020469E493A3F8E493A34003F68001F2" },
+{ 0x40, 0xA0, 0x1784, "08DFF48029E493A3F85407240CC8C333" },
+{ 0x40, 0xA0, 0x1794, "C4540F4420C8834004F456800146F6DF" },
+{ 0x40, 0xA0, 0x17A4, "E4800B01020408102040809011B5E47E" },
+{ 0x40, 0xA0, 0x17B4, "019360BCA3FF543F30E509541FFEE493" },
+{ 0x40, 0xA0, 0x17C4, "A360010ECF54C025E060A840B8E493A3" },
+{ 0x40, 0xA0, 0x17D4, "FAE493A3F8E493A3C8C582C8CAC583CA" },
+{ 0x40, 0xA0, 0x17E4, "F0A3C8C582C8CAC583CADFE9DEE780BE" },
+{ 0x40, 0xA0, 0x1288, "00" },
+{ 0x40, 0xA0, 0x7F92, "01" },
+{ 0x40, 0xA0, 0x7F92, "00" },
+{ 0, 0, 0, 0 }
+};
diff --git a/src/progs/icd2/base/icd_prog.cpp b/src/progs/icd2/base/icd_prog.cpp
new file mode 100644
index 0000000..6fadf06
--- /dev/null
+++ b/src/progs/icd2/base/icd_prog.cpp
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "icd_prog.h"
+
+#include "common/global/pfile.h"
+#include "progs/base/prog_config.h"
+#include "devices/list/device_list.h"
+
+bool Icd::ProgrammerBase::doUploadFirmware(PURL::File &file)
+{
+ const Device::Data &data = *Device::lister().data("16F876");
+ Pic::Memory memory(static_cast<const Pic::Data &>(data));
+ QStringList errors, warnings;
+ Pic::Memory::WarningTypes warningTypes;
+ if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) {
+ log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\": %2.").arg(file.url().pretty()).arg(errors[0]));
+ return false;
+ }
+ if ( warningTypes!=Pic::Memory::NoWarning ) {
+ log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 16F876 inside ICD."));
+ return false;
+ }
+ if ( !hardware().uploadFirmware(memory) ) {
+ log(Log::LineType::Error, i18n("Failed to upload firmware."));
+ return false;
+ }
+ return true;
+}
+
+bool Icd::ProgrammerBase::readFirmwareVersion()
+{
+ return hardware().getFirmwareVersion(_firmwareVersion);
+}
diff --git a/src/progs/icd2/base/icd_prog.h b/src/progs/icd2/base/icd_prog.h
new file mode 100644
index 0000000..ba6d9bb
--- /dev/null
+++ b/src/progs/icd2/base/icd_prog.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef ICD_PROG_H
+#define ICD_PROG_H
+
+#include "common/global/global.h"
+#include "icd.h"
+namespace PURL { class File; }
+
+namespace Icd
+{
+//----------------------------------------------------------------------------
+class ProgrammerBase : public ::Programmer::PicBase
+{
+Q_OBJECT
+public:
+ ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name)
+ : ::Programmer::PicBase(group, data, name) {}
+ virtual bool readFirmwareVersion();
+
+protected:
+ Hardware &hardware() { return static_cast<Hardware &>(*_hardware); }
+ virtual bool doUploadFirmware(PURL::File &file);
+};
+
+//----------------------------------------------------------------------------
+class Group : public ::Programmer::PicGroup
+{
+public:
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/microchip.cpp b/src/progs/icd2/base/microchip.cpp
new file mode 100644
index 0000000..b5229f6
--- /dev/null
+++ b/src/progs/icd2/base/microchip.cpp
@@ -0,0 +1,11 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "microchip.h"
+
+const uint Microchip::VENDOR_ID = 0x04d8;
diff --git a/src/progs/icd2/base/microchip.h b/src/progs/icd2/base/microchip.h
new file mode 100644
index 0000000..627b2ad
--- /dev/null
+++ b/src/progs/icd2/base/microchip.h
@@ -0,0 +1,19 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef MICROCHIP_H
+#define MICROCHIP_H
+
+#include <qstring.h>
+
+namespace Microchip
+{
+ extern const uint VENDOR_ID;
+} // namespace
+
+#endif
diff --git a/src/progs/icd2/base/promate2.xml b/src/progs/icd2/base/promate2.xml
new file mode 100644
index 0000000..9e85009
--- /dev/null
+++ b/src/progs/icd2/base/promate2.xml
@@ -0,0 +1,235 @@
+<!-- ************************************************************************* -->
+<!-- * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * -->
+<!-- * * -->
+<!-- * This program is free software; you can redistribute it and/or modify * -->
+<!-- * it under the terms of the GNU General Public License as published by * -->
+<!-- * the Free Software Foundation; either version 2 of the License, or * -->
+<!-- * (at your option) any later version. * -->
+<!-- *************************************************************************/-->
+<!DOCTYPE piklab>
+
+<programmer name="promate2">
+ <device name="12C508" first_revision="0x039900" os="0x10" part="0x00" socket="0x60" />
+ <device name="12C508A" first_revision="0x041001" os="0x10" part="0x02" socket="0x60" />
+ <device name="12C509" first_revision="0x039900" os="0x10" part="0x01" socket="0x60" />
+ <device name="12C509A" first_revision="0x041001" os="0x10" part="0x03" socket="0x60" />
+ <device name="12C671" first_revision="0x041001" os="0x10" part="0x04" socket="0x60" />
+ <device name="12C672" first_revision="0x040008" os="0x10" part="0x05" socket="0x60" />
+ <device name="12CE518" first_revision="0x041105" os="0x10" part="0x06" socket="0x60" />
+ <device name="12CE519" first_revision="0x041001" os="0x10" part="0x07" socket="0x60" />
+ <device name="12CE673" first_revision="0x041105" os="0x10" part="0x08" socket="0x60" />
+ <device name="12CE674" first_revision="0x041105" os="0x10" part="0x09" socket="0x60" />
+ <device name="12CR509A" first_revision="0x042945" os="0x10" part="0x0B" socket="0x60" />
+ <device name="12F508" first_revision="0x062026" os="0x10" part="0x1E" socket="0x60" />
+ <device name="12F509" first_revision="0x062026" os="0x10" part="0x1F" socket="0x60" />
+ <device name="12F629" first_revision="0x041105" os="0x10" part="0x11" socket="0x60" />
+ <device name="12F675" first_revision="0x041105" os="0x10" part="0x12" socket="0x60" />
+ <device name="12F683" first_revision="0x062021" os="0x10" part="0x1C" socket="0x60" />
+ <device name="16C432" first_revision="0x054001" os="0x10" part="0x24" socket="0xC0" />
+ <device name="16C433" first_revision="0x054001" os="0x10" part="0x0C" socket="0x60" />
+ <device name="16C505" first_revision="0x042216" os="0x10" part="0x0A" socket="0x60" />
+ <device name="16C54" first_revision="0x039900" os="0x10" part="0x00" socket="0xE0" />
+ <device name="16C54C" first_revision="0x042235" os="0x10" part="0x1B" socket="0xE0" />
+ <device name="16C55" first_revision="0x039900" os="0x10" part="0x04" socket="0xE0" />
+ <device name="16C554" first_revision="0x039900" os="0x10" part="0x0E" socket="0xC0" />
+ <device name="16C557" first_revision="0x059000" os="0x10" part="0x39" socket="0xE0" />
+ <device name="16C558" first_revision="0x039900" os="0x10" part="0x10" socket="0xC0" />
+ <device name="16C55A" first_revision="0x042401" os="0x10" part="0x1C" socket="0xE0" />
+ <device name="16C56" first_revision="0x039900" os="0x10" part="0x05" socket="0xE0" />
+ <device name="16C56A" first_revision="0x041101" os="0x10" part="0x17" socket="0xE0" />
+ <device name="16C57" first_revision="0x039900" os="0x10" part="0x06" socket="0xE0" />
+ <device name="16C57C" first_revision="0x042401" os="0x10" part="0x1D" socket="0xE0" />
+ <device name="16C58A" first_revision="0x039900" os="0x10" part="0x08" socket="0xE0" />
+ <device name="16C58B" first_revision="0x040008" os="0x10" part="0x0C" socket="0xE0" />
+ <device name="16C620" first_revision="0x039900" os="0x10" part="0x01" socket="0xC0" />
+ <device name="16C620A" first_revision="0x041101" os="0x10" part="0x17" socket="0xC0" />
+ <device name="16C621" first_revision="0x039900" os="0x10" part="0x02" socket="0xC0" />
+ <device name="16C621A" first_revision="0x041101" os="0x10" part="0x18" socket="0xC0" />
+ <device name="16C622" first_revision="0x039900" os="0x10" part="0x03" socket="0xC0" />
+ <device name="16C622A" first_revision="0x040008" os="0x10" part="0x19" socket="0xC0" />
+ <device name="16C62A" first_revision="0x039900" os="0x10" part="0x09" socket="0xB0" />
+ <device name="16C62B" first_revision="0x042235" os="0x10" part="0x1D" socket="0xB0" />
+ <device name="16C63" first_revision="0x039900" os="0x10" part="0x01" socket="0xB0" />
+ <device name="16C63A" first_revision="0x041105" os="0x10" part="0x19" socket="0xB0" />
+ <device name="16C642" first_revision="0x039900" os="0x10" part="0x0F" socket="0xB0" />
+ <device name="16C64A" first_revision="0x039900" os="0x10" part="0x0A" socket="0xB0" />
+ <device name="16C65A" first_revision="0x039900" os="0x10" part="0x04" socket="0xB0" />
+ <device name="16C65B" first_revision="0x041105" os="0x10" part="0x1A" socket="0xB0" />
+ <device name="16C66" first_revision="0x039900" os="0x10" part="0x12" socket="0xB0" />
+ <device name="16C662" first_revision="0x039900" os="0x10" part="0x11" socket="0xB0" />
+ <device name="16C67" first_revision="0x039900" os="0x10" part="0x13" socket="0xB0" />
+ <device name="16C71" first_revision="0x039900" os="0x10" part="0x05" socket="0xC0" />
+ <device name="16C710" first_revision="0x039900" os="0x10" part="0x11" socket="0xC0" />
+ <device name="16C711" first_revision="0x039900" os="0x10" part="0x12" socket="0xC0" />
+ <device name="16C712" first_revision="0x050003" os="0x10" part="0x14" socket="0xC0" />
+ <device name="16C715" first_revision="0x039900" os="0x10" part="0x13" socket="0xC0" />
+ <device name="16C716" first_revision="0x050003" os="0x10" part="0x15" socket="0xC0" />
+ <device name="16C717" first_revision="0x050036" os="0x10" part="0x23" socket="0xC0" />
+ <device name="16C72" first_revision="0x039900" os="0x10" part="0x0B" socket="0xB0" />
+ <device name="16C72A" first_revision="0x042235" os="0x10" part="0x1E" socket="0xB0" />
+ <device name="16C73A" first_revision="0x039900" os="0x10" part="0x06" socket="0xB0" />
+ <device name="16C73B" first_revision="0x041105" os="0x10" part="0x1B" socket="0xB0" />
+ <device name="16C745" first_revision="0x051010" os="0x10" part="0x2F" socket="0xB0" />
+ <device name="16C74A" first_revision="0x039900" os="0x10" part="0x08" socket="0xB0" />
+ <device name="16C74B" first_revision="0x041105" os="0x10" part="0x1C" socket="0xB0" />
+ <device name="16C76" first_revision="0x039900" os="0x10" part="0x14" socket="0xB0" />
+ <device name="16C765" first_revision="0x051010" os="0x10" part="0x30" socket="0xB0" />
+ <device name="16C77" first_revision="0x039900" os="0x10" part="0x15" socket="0xB0" />
+ <device name="16C770" first_revision="0x050036" os="0x10" part="0x22" socket="0xC0" />
+ <device name="16C771" first_revision="0x050036" os="0x10" part="0x21" socket="0xC0" />
+ <device name="16C773" first_revision="0x042945" os="0x10" part="0x20" socket="0xB0" />
+ <device name="16C774" first_revision="0x042236" os="0x10" part="0x1F" socket="0xB0" />
+ <device name="16C781" first_revision="0x056000" os="0x10" part="0x27" socket="0xC0" />
+ <device name="16C782" first_revision="0x054051" os="0x10" part="0x28" socket="0xC0" />
+ <device name="16C923" first_revision="0x039900" os="0x10" part="0x00" socket="0x90" />
+ <device name="16C924" first_revision="0x039900" os="0x10" part="0x01" socket="0x90" />
+ <device name="16C925" first_revision="0x052031" os="0x10" part="0x02" socket="0x90" />
+ <device name="16C926" first_revision="0x052031" os="0x10" part="0x03" socket="0x90" />
+ <device name="16CE623" first_revision="0x042235" os="0x10" part="0x1A" socket="0xC0" />
+ <device name="16CE624" first_revision="0x042235" os="0x10" part="0x1B" socket="0xC0" />
+ <device name="16CE625" first_revision="0x042216" os="0x10" part="0x1C" socket="0xC0" />
+ <device name="16CR54" first_revision="0x039900" os="0x10" part="0x02" socket="0xE0" />
+ <device name="16CR54A" first_revision="0x039900" os="0x10" part="0x0D" socket="0xE0" />
+ <device name="16CR54C" first_revision="0x042945" os="0x10" part="0x1A" socket="0xE0" />
+ <device name="16CR56A" first_revision="0x041105" os="0x10" part="0x18" socket="0xE0" />
+ <device name="16CR57C" first_revision="0x042945" os="0x10" part="0x1E" socket="0xE0" />
+ <device name="16CR58B" first_revision="0x040008" os="0x10" part="0x19" socket="0xE0" />
+ <device name="16CR62" first_revision="0x039900" os="0x10" part="0x0C" socket="0xB0" />
+ <device name="16CR620A" first_revision="0x042945" os="0x10" part="0x16" socket="0xC0" />
+ <device name="16CR63" first_revision="0x040008" os="0x10" part="0x16" socket="0xB0" />
+ <device name="16CR64" first_revision="0x039900" os="0x10" part="0x0D" socket="0xB0" />
+ <device name="16CR65" first_revision="0x040008" os="0x10" part="0x17" socket="0xB0" />
+ <device name="16CR72" first_revision="0x040008" os="0x10" part="0x18" socket="0xB0" />
+ <device name="16CR83" first_revision="0x039900" os="0x10" part="0x0A" socket="0xC0" />
+ <device name="16CR84" first_revision="0x039900" os="0x10" part="0x0B" socket="0xC0" />
+ <device name="16F505" first_revision="0x062026" os="0x10" part="0x1D" socket="0x60" />
+ <device name="16F54" first_revision="0x061027" os="0x10" part="0x20" socket="0xE0" />
+ <device name="16F57" first_revision="0x061027" os="0x10" part="0x21" socket="0xE0" />
+ <device name="16F627" first_revision="0x051010" os="0x10" part="0x1F" socket="0xC0" />
+ <device name="16F627A" first_revision="0x059005" os="0x10" part="0x2B" socket="0xC0" />
+ <device name="16F628" first_revision="0x051010" os="0x10" part="0x20" socket="0xC0" />
+ <device name="16F628A" first_revision="0x059005" os="0x10" part="0x2C" socket="0xC0" />
+ <device name="16F630" first_revision="0x058005" os="0x10" part="0x16" socket="0x60" />
+ <device name="16F636" first_revision="0x062008" os="0x10" part="0x1B" socket="0x60" />
+ <device name="16F639" first_revision="0x062008" os="0x10" part="0x1B" socket="0x60" />
+ <device name="16F648A" first_revision="0x059021" os="0x10" part="0x2F" socket="0xC0" />
+ <device name="16F676" first_revision="0x058005" os="0x10" part="0x15" socket="0x60" />
+ <device name="16F684" first_revision="0x061005" os="0x10" part="0x19" socket="0x60" />
+ <device name="16F688" first_revision="0x061021" os="0x10" part="0x1A" socket="0x60" />
+ <device name="16F716" first_revision="0x061010" os="0x10" part="0x30" socket="0xC0" />
+ <device name="16F72" first_revision="0x056020" os="0x10" part="0x40" socket="0xB0" />
+ <device name="16F73" first_revision="0x053001" os="0x10" part="0x32" socket="0xB0" />
+ <device name="16F737" first_revision="0x060005" os="0x10" part="0x41" socket="0xB0" />
+ <device name="16F74" first_revision="0x053001" os="0x10" part="0x33" socket="0xB0" />
+ <device name="16F747" first_revision="0x060005" os="0x10" part="0x42" socket="0xB0" />
+ <device name="16F76" first_revision="0x052026" os="0x10" part="0x31" socket="0xB0" />
+ <device name="16F767" first_revision="0x060005" os="0x10" part="0x43" socket="0xB0" />
+ <device name="16F77" first_revision="0x051010" os="0x10" part="0x2E" socket="0xB0" />
+ <device name="16F777" first_revision="0x060005" os="0x10" part="0x44" socket="0xB0" />
+ <device name="16F818" first_revision="0x058021" os="0x10" part="0x29" socket="0xC0" />
+ <device name="16F819" first_revision="0x058021" os="0x10" part="0x2A" socket="0xC0" />
+ <device name="16F83" first_revision="0x039900" os="0x10" part="0x0D" socket="0xC0" />
+ <device name="16F84" first_revision="0x039900" os="0x10" part="0x0C" socket="0xC0" />
+ <device name="16F84A" first_revision="0x042229" os="0x10" part="0x1D" socket="0xC0" />
+ <device name="16F87" first_revision="0x059001" os="0x10" part="0x2D" socket="0xC0" />
+ <device name="16F870" first_revision="0x051010" os="0x10" part="0x2B" socket="0xB0" />
+ <device name="16F871" first_revision="0x051010" os="0x10" part="0x2C" socket="0xB0" />
+ <device name="16F872" first_revision="0x050025" os="0x10" part="0x2A" socket="0xB0" />
+ <device name="16F873" first_revision="0x042945" os="0x10" part="0x24" socket="0xB0" />
+ <device name="16F873A" first_revision="0x058000" os="0x10" part="0x3F" socket="0xB0" />
+ <device name="16F874" first_revision="0x042945" os="0x10" part="0x23" socket="0xB0" />
+ <device name="16F874A" first_revision="0x058000" os="0x10" part="0x3E" socket="0xB0" />
+ <device name="16F876" first_revision="0x042945" os="0x10" part="0x22" socket="0xB0" />
+ <device name="16F876A" first_revision="0x058000" os="0x10" part="0x3D" socket="0xB0" />
+ <device name="16F877" first_revision="0x042235" os="0x10" part="0x21" socket="0xB0" />
+ <device name="16F877A" first_revision="0x058000" os="0x10" part="0x3C" socket="0xB0" />
+ <device name="16F88" first_revision="0x059001" os="0x10" part="0x2E" socket="0xC0" />
+ <device name="16HV540" first_revision="0x042945" os="0x10" part="0x1F" socket="0xE0" />
+ <device name="17C42" first_revision="0x039900" os="0x12" part="0x00" socket="0xD0" />
+ <device name="17C42A" first_revision="0x039900" os="0x12" part="0x01" socket="0xD0" />
+ <device name="17C43" first_revision="0x039900" os="0x12" part="0x02" socket="0xD0" />
+ <device name="17C44" first_revision="0x039900" os="0x12" part="0x03" socket="0xD0" />
+ <device name="17C752" first_revision="0x042235" os="0x12" part="0x07" socket="0xD0" />
+ <device name="17C756" first_revision="0x039900" os="0x12" part="0x06" socket="0xD0" />
+ <device name="17C756A" first_revision="0x042235" os="0x12" part="0x09" socket="0xD0" />
+ <device name="17C762" first_revision="0x042235" os="0x12" part="0x0A" socket="0xD0" />
+ <device name="17C766" first_revision="0x042216" os="0x12" part="0x08" socket="0xD0" />
+ <device name="17CR42" first_revision="0x039900" os="0x12" part="0x04" socket="0xD0" />
+ <device name="17CR43" first_revision="0x039900" os="0x12" part="0x05" socket="0xD0" />
+ <device name="18C242" first_revision="0x050001" os="0x11" part="0x29" socket="0xB0" />
+ <device name="18C252" first_revision="0x050001" os="0x11" part="0x27" socket="0xB0" />
+ <device name="18C442" first_revision="0x050001" os="0x11" part="0x28" socket="0xB0" />
+ <device name="18C452" first_revision="0x050001" os="0x11" part="0x26" socket="0xB0" />
+ <device name="18C601" first_revision="0x054001" os="0x11" part="0x0D" socket="0xD0" />
+ <device name="18C658" first_revision="0x051010" os="0x11" part="0x0B" socket="0xD0" />
+ <device name="18C801" first_revision="0x054001" os="0x11" part="0x0E" socket="0xD0" />
+ <device name="18C858" first_revision="0x051010" os="0x11" part="0x0C" socket="0xD0" />
+ <device name="18F1220" first_revision="0x058001" os="0x11" part="0x2E" socket="0xC0" />
+ <device name="18F1320" first_revision="0x058001" os="0x11" part="0x2D" socket="0xC0" />
+ <device name="18F2220" first_revision="0x057001" os="0x11" part="0x45" socket="0xB0" />
+ <device name="18F2320" first_revision="0x057001" os="0x11" part="0x44" socket="0xB0" />
+ <device name="18F2331" first_revision="0x061001" os="0x11" part="0x4A" socket="0xB0" />
+ <device name="18F242" first_revision="0x056002" os="0x11" part="0x34" socket="0xB0" />
+ <device name="18F2431" first_revision="0x061001" os="0x11" part="0x4B" socket="0xB0" />
+ <device name="18F2439" first_revision="0x059005" os="0x11" part="0x46" socket="0xB0" />
+ <device name="18F248" first_revision="0x056002" os="0x11" part="0x38" socket="0xB0" />
+ <device name="18F2515" first_revision="0x062024" os="0x11" part="0x55" socket="0xB0" />
+ <device name="18F252" first_revision="0x056002" os="0x11" part="0x35" socket="0xB0" />
+ <device name="18F2525" first_revision="0x062024" os="0x11" part="0x56" socket="0xB0" />
+ <device name="18F2539" first_revision="0x059005" os="0x11" part="0x47" socket="0xB0" />
+ <device name="18F258" first_revision="0x056002" os="0x11" part="0x39" socket="0xB0" />
+ <device name="18F2610" first_revision="0x062027" os="0x11" part="0x59" socket="0xB0" />
+ <device name="18F2620" first_revision="0x062027" os="0x11" part="0x4F" socket="0xB0" />
+ <device name="18F2680" first_revision="0x062004" os="0x11" part="0x52" socket="0xB0" />
+ <device name="18F4220" first_revision="0x057001" os="0x11" part="0x43" socket="0xB0" />
+ <device name="18F4320" first_revision="0x057001" os="0x11" part="0x42" socket="0xB0" />
+ <device name="18F4331" first_revision="0x061001" os="0x11" part="0x4C" socket="0xB0" />
+ <device name="18F442" first_revision="0x056002" os="0x11" part="0x36" socket="0xB0" />
+ <device name="18F4431" first_revision="0x061001" os="0x11" part="0x4D" socket="0xB0" />
+ <device name="18F4439" first_revision="0x059005" os="0x11" part="0x48" socket="0xB0" />
+ <device name="18F448" first_revision="0x056002" os="0x11" part="0x3A" socket="0xB0" />
+ <device name="18F4515" first_revision="0x062024" os="0x11" part="0x57" socket="0xB0" />
+ <device name="18F452" first_revision="0x056002" os="0x11" part="0x37" socket="0xB0" />
+ <device name="18F4525" first_revision="0x062024" os="0x11" part="0x58" socket="0xB0" />
+ <device name="18F4539" first_revision="0x059005" os="0x11" part="0x49" socket="0xB0" />
+ <device name="18F458" first_revision="0x056002" os="0x11" part="0x3B" socket="0xB0" />
+ <device name="18F4610" first_revision="0x062027" os="0x11" part="0x5A" socket="0xB0" />
+ <device name="18F4620" first_revision="0x061007" os="0x11" part="0x4E" socket="0xB0" />
+ <device name="18F4680" first_revision="0x062004" os="0x11" part="0x51" socket="0xB0" />
+ <device name="18F6410" first_revision="0x062011" os="0x11" part="0x1F" socket="0xD0" />
+ <device name="18F6490" first_revision="0x062011" os="0x11" part="0x20" socket="0xD0" />
+ <device name="18F6520" first_revision="0x059015" os="0x11" part="0x13" socket="0xD0" />
+ <device name="18F6525" first_revision="0x060001" os="0x11" part="0x15" socket="0xD0" />
+ <device name="18F6585" first_revision="0x060001" os="0x11" part="0x16" socket="0xD0" />
+ <device name="18F6620" first_revision="0x057002" os="0x11" part="0x12" socket="0xD0" />
+ <device name="18F6621" first_revision="0x060001" os="0x11" part="0x17" socket="0xD0" />
+ <device name="18F6680" first_revision="0x060001" os="0x11" part="0x18" socket="0xD0" />
+ <device name="18F6720" first_revision="0x057002" os="0x11" part="0x11" socket="0xD0" />
+ <device name="18F8410" first_revision="0x062011" os="0x11" part="0x1E" socket="0xD0" />
+ <device name="18F8490" first_revision="0x062011" os="0x11" part="0x1D" socket="0xD0" />
+ <device name="18F8520" first_revision="0x059015" os="0x11" part="0x14" socket="0xD0" />
+ <device name="18F8525" first_revision="0x060001" os="0x11" part="0x19" socket="0xD0" />
+ <device name="18F8585" first_revision="0x060001" os="0x11" part="0x1A" socket="0xD0" />
+ <device name="18F8620" first_revision="0x057002" os="0x11" part="0x10" socket="0xD0" />
+ <device name="18F8621" first_revision="0x060001" os="0x11" part="0x1B" socket="0xD0" />
+ <device name="18F8680" first_revision="0x060001" os="0x11" part="0x1C" socket="0xD0" />
+ <device name="18F8720" first_revision="0x057002" os="0x11" part="0x0F" socket="0xD0" />
+ <device name="30F2010" first_revision="0x060000" os="0x13" part="0x04" socket="0x50" />
+ <device name="30F2011" first_revision="0x060000" os="0x13" part="0x05" socket="0x50" />
+ <device name="30F2012" first_revision="0x060000" os="0x13" part="0x06" socket="0x50" />
+ <device name="30F3011" first_revision="0x060000" os="0x13" part="0x08" socket="0x50" />
+ <device name="30F3012" first_revision="0x060000" os="0x13" part="0x09" socket="0x50" />
+ <device name="30F3013" first_revision="0x060000" os="0x13" part="0x0A" socket="0x50" />
+ <device name="30F3014" first_revision="0x060000" os="0x13" part="0x0B" socket="0x50" />
+ <device name="30F4011" first_revision="0x060000" os="0x13" part="0x0C" socket="0x50" />
+ <device name="30F4012" first_revision="0x060000" os="0x13" part="0x0D" socket="0x50" />
+ <device name="30F4013" first_revision="0x060000" os="0x13" part="0x17" socket="0x50" />
+ <device name="30F5011" first_revision="0x060000" os="0x13" part="0x0E" socket="0x50" />
+ <device name="30F5013" first_revision="0x060000" os="0x13" part="0x0F" socket="0x50" />
+ <device name="30F5015" first_revision="0x060000" os="0x13" part="0x16" socket="0x50" />
+ <device name="30F6010" first_revision="0x060000" os="0x13" part="0x10" socket="0x50" />
+ <device name="30F6011" first_revision="0x060000" os="0x13" part="0x11" socket="0x50" />
+ <device name="30F6012" first_revision="0x060000" os="0x13" part="0x12" socket="0x50" />
+ <device name="30F6013" first_revision="0x060000" os="0x13" part="0x13" socket="0x50" />
+ <device name="30F6014" first_revision="0x060000" os="0x13" part="0x14" socket="0x50" />
+</programmer> \ No newline at end of file