summaryrefslogtreecommitdiffstats
path: root/src/progs/pickit2/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/pickit2/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/pickit2/base')
-rw-r--r--src/progs/pickit2/base/Makefile.am12
-rw-r--r--src/progs/pickit2/base/base.pro6
-rw-r--r--src/progs/pickit2/base/pickit.cpp337
-rw-r--r--src/progs/pickit2/base/pickit.h137
-rw-r--r--src/progs/pickit2/base/pickit2.cpp447
-rw-r--r--src/progs/pickit2/base/pickit2.h123
-rw-r--r--src/progs/pickit2/base/pickit2.xml114
-rw-r--r--src/progs/pickit2/base/pickit2_data.h24
-rw-r--r--src/progs/pickit2/base/pickit2_prog.cpp78
-rw-r--r--src/progs/pickit2/base/pickit2_prog.h50
-rw-r--r--src/progs/pickit2/base/pickit_prog.cpp54
-rw-r--r--src/progs/pickit2/base/pickit_prog.h45
12 files changed, 1427 insertions, 0 deletions
diff --git a/src/progs/pickit2/base/Makefile.am b/src/progs/pickit2/base/Makefile.am
new file mode 100644
index 0000000..a436012
--- /dev/null
+++ b/src/progs/pickit2/base/Makefile.am
@@ -0,0 +1,12 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libpickit2.la
+libpickit2_la_SOURCES = pickit2_data.cpp pickit.cpp pickit_prog.cpp \
+ pickit2.cpp pickit2_prog.cpp
+libpickit2_la_DEPENDENCIES = pickit2_data.cpp
+
+noinst_DATA = pickit2.xml
+pickit2_data.cpp: ../xml/xml_pickit2_parser pickit2.xml
+ ../xml/xml_pickit2_parser
+CLEANFILES = pickit2_data.cpp
diff --git a/src/progs/pickit2/base/base.pro b/src/progs/pickit2/base/base.pro
new file mode 100644
index 0000000..3a229e3
--- /dev/null
+++ b/src/progs/pickit2/base/base.pro
@@ -0,0 +1,6 @@
+STOPDIR = ../../../..
+include($${STOPDIR}/lib.pro)
+
+TARGET = pickit2
+HEADERS += pickit.h pickit_prog.h pickit2.h pickit2_data.h pickit2_prog.h
+SOURCES += pickit.cpp pickit_prog.cpp pickit2.cpp pickit2_data.cpp pickit2_prog.cpp
diff --git a/src/progs/pickit2/base/pickit.cpp b/src/progs/pickit2/base/pickit.cpp
new file mode 100644
index 0000000..7da2d18
--- /dev/null
+++ b/src/progs/pickit2/base/pickit.cpp
@@ -0,0 +1,337 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pickit.h"
+
+#include "devices/base/device_group.h"
+#include "progs/base/prog_group.h"
+
+//-----------------------------------------------------------------------------
+Pickit::Array::Array(uint length, uchar fillChar, PrintMode mode)
+ : _fillChar(fillChar), _mode(mode), _data(length)
+{
+ _data.fill(fillChar);
+}
+
+QString Pickit::Array::pretty() const
+{
+ int end = _data.count() - 1;
+ for (; end>=0; end--)
+ if ( _data[end]!=_fillChar ) break;
+ QString s;
+ for (int i=0; i<=end; i++) s += toPrintable(_data[i], _mode);
+ return s;
+}
+
+//-----------------------------------------------------------------------------
+Pickit::USBPort::USBPort(uint deviceId, Log::Base &log)
+ : Port::USB(log, Microchip::VENDOR_ID, deviceId, CONFIG_VENDOR, 0)
+{}
+
+bool Pickit::USBPort::command(uchar c)
+{
+ Array a = array();
+ a._data[0] = c;
+ return command(a);
+}
+
+bool Pickit::USBPort::command(const char *s)
+{
+ Array a = array();
+ if (s) {
+ Q_ASSERT( strlen(s)<=a.length() );
+ for (uint i=0; i<strlen(s); i++) a._data[i] = s[i];
+ }
+ return command(a);
+}
+
+bool Pickit::USBPort::command(const Array &cmd)
+{
+ log(Log::DebugLevel::Extra, QString("send command: \"%1\"").arg(cmd.pretty()));
+ return write(writeEndPoint(), (const char *)cmd._data.data(), cmd.length());
+}
+
+bool Pickit::USBPort::receive(Pickit::Array &array)
+{
+ if ( !read(readEndPoint(), (char *)array._data.data(), array.length()) ) return false;
+ log(Log::DebugLevel::Max, QString("received: \"%1\"").arg(array.pretty()));
+ return true;
+}
+
+bool Pickit::USBPort::getMode(VersionData &version, ::Programmer::Mode &mode)
+{
+ if ( !command('v') ) return false;
+ Array a = array();
+ if ( !receive(a) ) return false;
+ if ( a[5]=='B' ) {
+ version = VersionData(a[6], a[7], 0);
+ mode = ::Programmer::BootloadMode;
+ } else {
+ version = VersionData(a[0], a[1], a[2]);
+ mode = ::Programmer::NormalMode;
+ }
+ return true;
+}
+
+bool Pickit::USBPort::receiveWords(uint nbBytesWord, uint nbRead, QValueVector<uint> &words, uint offset)
+{
+ log(Log::DebugLevel::Max, QString("receive words nbBytesWord=%1 nbRead=%2 offset=%3").arg(nbBytesWord).arg(nbRead).arg(offset));
+ Array a = array();
+ QMemArray<uchar> data(nbRead*a.length());
+ uint l = 0;
+ for (uint i=0; i<nbRead; i++) {
+ if ( !receive(a) ) return false;
+ for (uint k=offset; k<a.length(); k++) {
+ data[l] = a[k];
+ l++;
+ }
+ }
+ words.resize(data.count()/nbBytesWord);
+ for (uint i=0; i<uint(words.count()); i++) {
+ words[i] = 0;
+ for (uint k=0; k<nbBytesWord; k++) words[i] |= data[nbBytesWord*i + k] << (8*k);
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+Pickit::Hardware::Hardware(::Programmer::Base &base, USBPort *port)
+ : ::Programmer::PicHardware(base, port, QString::null)
+{}
+
+bool Pickit::Hardware::internalConnectHardware()
+{
+ return port().open();
+}
+
+bool Pickit::Hardware::setTargetPower(uint v)
+{
+ Array cmd = port().array();
+ cmd[0] = 'V';
+ cmd[1] = v;
+ return port().command(cmd);
+}
+
+bool Pickit::Hardware::writeWords(uint max, char c, uint nbBytesWord,
+ uint &i, const Device::Array &data)
+{
+ Q_ASSERT( i<data.count() );
+ Q_ASSERT( nbBytesWord==1 || nbBytesWord==2 );
+ Array cmd = port().array();
+ uint n = (nbBytesWord==1 ? 2 : 3);
+ Q_ASSERT( n*max<=cmd.length() );
+ for (uint k=0; k<max; k++) {
+ cmd[n*k] = c;
+ cmd[n*k+1] = data[i].byte(0);
+ if ( nbBytesWord==2 ) cmd[n*k+2] = data[i].byte(1);
+ i++;
+ if ( i>=data.count() ) break;
+ }
+ return port().command(cmd);
+}
+
+bool Pickit::Hardware::regenerateOsccal(BitValue &newValue)
+{
+ if ( !setTargetPower(Osc2_5kHz) ) return false;
+ if ( !setTargetPower(PowerOn + Osc2_5kHz) ) return false;
+ Port::usleep(400000); // 400 ms
+ if ( !setTargetPower(PowerOff) ) return false;
+ Pickit::Array cmd = port().array();
+ cmd[0] = 'P';
+ cmd[1] = 'I';
+ cmd[2] = 120;
+ cmd[3] = 0;
+ cmd[4] = 'r';
+ cmd[5] = 'p';
+ if ( !port().command(cmd) ) return false;
+ QValueVector<uint> words;
+ if ( !port().receiveWords(1, 1, words) ) return false;
+ newValue = words[7] | 0x3400;
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool Pickit::DeviceSpecific::setPowerOn()
+{
+ return hardware().port().command(entryMode());
+}
+
+bool Pickit::DeviceSpecific::setPowerOff()
+{
+ return hardware().port().command('p');
+}
+
+bool Pickit::DeviceSpecific::setTargetPowerOn(bool on)
+{
+ return hardware().setTargetPower(on ? PowerOn : PowerOff);
+}
+
+//----------------------------------------------------------------------------
+bool Pickit::BMDeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ data.resize(device().nbWords(type));
+ gotoMemory(type);
+ QValueVector<uint> words;
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Config:
+ case Pic::MemoryRangeType::Code:
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::CalBackup:
+ case Pic::MemoryRangeType::UserId:
+ case Pic::MemoryRangeType::DeviceId:
+ for (uint i=0; i<data.count();) {
+ if ( !hardware().port().command('R') ) return false;
+ if ( !hardware().port().receiveWords(2, 1, words) ) return false;
+ for (uint k=0; k<uint(words.count()); k++) {
+ data[i] = words[k];
+ if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
+ i++;
+ if ( i>=data.count() ) break;
+ }
+ }
+ break;
+ case Pic::MemoryRangeType::Eeprom:
+ for (uint i=0; i<data.count();) {
+ if ( !hardware().port().command('r') ) return false; // #### not sure this is correct for Pickit1: "rrrrrrrr" used by usb_pickit
+ if ( !hardware().port().receiveWords(1, 1, words) ) return false;
+ for (uint k=0; k<uint(words.count()); k++) {
+ data[i] = words[k];
+ if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
+ i++;
+ if ( i>=data.count() ) break;
+ }
+ }
+ break;
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false;
+ }
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom )
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+}
+
+bool Pickit::BMDeviceSpecific::incrementPC(uint nb)
+{
+ Pickit::Array cmd = hardware().port().array();
+ cmd[0] = 'I';
+ cmd[1] = nb & 0xFF;
+ cmd[2] = (nb >> 8) & 0xFF;
+ return hardware().port().command(cmd);
+}
+
+bool Pickit::BMDeviceSpecific::doEraseRange(Pic::MemoryRangeType type)
+{
+ Q_ASSERT( type==Pic::MemoryRangeType::Code );
+ return hardware().port().command('E');
+}
+
+bool Pickit::BMDeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ // #### TODO: speed optimize...
+ Q_UNUSED(force);
+ gotoMemory(type);
+ uint nb = nbWrites(type);
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Config:
+ case Pic::MemoryRangeType::Code:
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::UserId:
+ for (uint i=0; i<data.count(); )
+ hardware().writeWords(nb, writeCode(), 2, i, data);
+ break;
+ case Pic::MemoryRangeType::Eeprom:
+ for (uint i=0; i<data.count(); )
+ hardware().writeWords(nb, writeData(), 1, i, data);
+ break;
+ case Pic::MemoryRangeType::CalBackup:
+ case Pic::MemoryRangeType::DeviceId:
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false;
+ }
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom )
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool Pickit::Baseline::gotoMemory(Pic::MemoryRangeType type)
+{
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Config:
+ case Pic::MemoryRangeType::Eeprom: return true;
+ case Pic::MemoryRangeType::Code:
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::UserId:
+ case Pic::MemoryRangeType::CalBackup: return incrementPC(1+device().range(type).start.toUInt());
+ case Pic::MemoryRangeType::DeviceId:
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool Pickit::P16F::gotoMemory(Pic::MemoryRangeType type)
+{
+ Pickit::Array cmd = hardware().port().array();
+ cmd[0] = 'C';
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Code: return true;
+ case Pic::MemoryRangeType::Eeprom: return true;
+ case Pic::MemoryRangeType::UserId: return hardware().port().command(cmd);
+ case Pic::MemoryRangeType::DeviceId:
+ cmd[1] = 'I';
+ cmd[2] = 0x06;
+ cmd[3] = 0x00;
+ return hardware().port().command(cmd);
+ case Pic::MemoryRangeType::Config:
+ cmd[1] = 'I';
+ cmd[2] = 0x07;
+ cmd[3] = 0x00;
+ return hardware().port().command(cmd);
+ case Pic::MemoryRangeType::Cal:
+ if ( device().range(type).start==device().range(Pic::MemoryRangeType::Code).end+1 )
+ return incrementPC(device().range(type).start.toUInt());
+ cmd[1] = 'I';
+ cmd[2] = 0x08;
+ cmd[3] = 0x00;
+ return hardware().port().command(cmd);
+ case Pic::MemoryRangeType::CalBackup:
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+bool Pickit::P16F::doErase(bool)
+{
+ Pickit::Array cmd = hardware().port().array();
+ cmd[0] = 'C';
+ cmd[1] = writeCode();
+ cmd[2] = 0xFF;
+ cmd[3] = 0x3F;
+ cmd[4] = 'E';
+ cmd[5] = 'e';
+ return hardware().port().command(cmd);
+}
+
+bool Pickit::P16F::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return hardware().port().command('e');
+ return BMDeviceSpecific::doEraseRange(type);
+}
diff --git a/src/progs/pickit2/base/pickit.h b/src/progs/pickit2/base/pickit.h
new file mode 100644
index 0000000..741ed61
--- /dev/null
+++ b/src/progs/pickit2/base/pickit.h
@@ -0,0 +1,137 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PICKIT_H
+#define PICKIT_H
+
+#include "progs/icd2/base/microchip.h"
+#include "common/port/usb_port.h"
+#include "devices/pic/pic/pic_memory.h"
+#include "devices/pic/prog/pic_prog.h"
+
+namespace Pickit
+{
+enum PowerType { PowerOff = 0, PowerOn = 1, Osc2_5kHz = 2 };
+
+//-----------------------------------------------------------------------------
+class Array
+{
+public:
+ uint length() const { return _data.count(); }
+ QString pretty() const;
+ uchar &operator[](uint i) { return _data[i]; }
+ uchar operator[](uint i) const { return _data[i]; }
+
+protected:
+ Array(uint length, uchar fillChar, PrintMode mode);
+
+private:
+ uchar _fillChar;
+ PrintMode _mode;
+ QMemArray<uchar> _data;
+
+ friend class USBPort;
+};
+
+//-----------------------------------------------------------------------------
+class USBPort : public Port::USB
+{
+public:
+ USBPort(uint deviceId, Log::Base &manager);
+ virtual Array array() const = 0;
+ bool command(const Array &cmd);
+ bool command(uchar c);
+ bool command(const char *s);
+ bool receive(Array &data);
+ bool getMode(VersionData &version, ::Programmer::Mode &mode);
+ bool receiveWords(uint nbBytesWord, uint nbRead, QValueVector<uint> &data, uint offset = 0);
+
+protected:
+ virtual uint writeEndPoint() const = 0;
+ virtual uint readEndPoint() const = 0;
+
+private:
+ virtual uint timeout(uint) const { return 10000; } // 10s
+ enum { CONFIG_HID = 1, // use HID for pickit configuration
+ CONFIG_VENDOR = 2 // vendor specific configuration
+ };
+};
+
+//-----------------------------------------------------------------------------
+class Hardware : public ::Programmer::PicHardware
+{
+public:
+ Hardware(::Programmer::Base &base, USBPort *port);
+ bool setTargetPower(uint value);
+ USBPort &port() { return static_cast<USBPort &>(*_port); }
+ const USBPort &port() const { return static_cast<USBPort &>(*_port); }
+ bool writeWords(uint max, char c, uint nbBytesWord,
+ uint &i, const Device::Array &data);
+ bool regenerateOsccal(BitValue &newValue);
+
+protected:
+ virtual bool internalConnectHardware();
+};
+
+//-----------------------------------------------------------------------------
+class DeviceSpecific : public ::Programmer::PicDeviceSpecific
+{
+public:
+ DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {}
+ virtual bool canEraseAll() const { return true; }
+ virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ); }
+ virtual bool canReadRange(Pic::MemoryRangeType) const { return true; }
+ virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; }
+ Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); }
+ virtual bool init() = 0;
+ virtual bool setPowerOn();
+ virtual bool setPowerOff();
+ virtual bool setTargetPowerOn(bool on);
+ virtual char entryMode() const = 0;
+};
+
+//-----------------------------------------------------------------------------
+class BMDeviceSpecific : public DeviceSpecific
+{
+public:
+ BMDeviceSpecific(::Programmer::Base &base) : DeviceSpecific(base) {}
+ virtual bool gotoMemory(Pic::MemoryRangeType type) = 0;
+ virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata);
+ virtual bool incrementPC(uint nb);
+ virtual uint nbWrites(Pic::MemoryRangeType type) const = 0;
+ virtual char writeCode() const = 0;
+ virtual char writeData() const = 0;
+ virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force);
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+};
+
+//-----------------------------------------------------------------------------
+class Baseline : public BMDeviceSpecific
+{
+public:
+ Baseline(::Programmer::Base &base) : BMDeviceSpecific(base) {}
+ virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code); }
+ virtual bool gotoMemory(Pic::MemoryRangeType type);
+ virtual char writeCode() const { return 'w'; }
+ virtual char writeData() const { return 'D'; }
+};
+
+class P16F : public BMDeviceSpecific
+{
+public:
+ P16F(::Programmer::Base &base) : BMDeviceSpecific(base) {}
+ virtual bool gotoMemory(Pic::MemoryRangeType type);
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool);
+ virtual char writeCode() const { return 'W'; }
+ virtual char writeData() const { return 'D'; }
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/pickit2/base/pickit2.cpp b/src/progs/pickit2/base/pickit2.cpp
new file mode 100644
index 0000000..6458fa2
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2.cpp
@@ -0,0 +1,447 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pickit2.h"
+
+#include "common/global/global.h"
+#include "devices/list/device_list.h"
+#include "common/port/port.h"
+
+//-----------------------------------------------------------------------------
+void Pickit2::USBPort::fillCommand(Pickit::Array &cmd, uchar command, uint nbBytes,
+ uint address, uint i, bool longAddress) const
+{
+ cmd[i] = command;
+ cmd[i+1] = nbBytes;
+ cmd[i+2] = address & 0xFF;
+ cmd[i+3] = (address >> 8) & 0xFF;
+ if (longAddress) cmd[i+4] = (address >> 16) & 0xFF;
+}
+
+Pickit::Array Pickit2::USBPort::createCommand(uchar c, uint nbBytes, uint address, bool longAddress) const
+{
+ Array cmd;
+ fillCommand(cmd, c, nbBytes, address, 0, longAddress);
+ return cmd;
+}
+
+bool Pickit2::USBPort::readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor)
+{
+ const Pic::Data *device = static_cast<const Pic::Data *>(Device::lister().data("18F2455"));
+ log(Log::DebugLevel::Normal, " Read pickit2 firmware");
+ for (uint i=0; i<data.count(); i+=16) { // 2 bytes/word and 32 bytes/command max
+ uint start = 0;
+ for (; start<16; start++) if ( data[i + start].isInitialized() ) break;
+ if ( start==16 ) continue;
+ uint end = 15;
+ for (; end>start; end--) if ( data[i + end].isInitialized() ) break;
+ uint nb = end - start + 1;
+ Pickit::Array cmd = createCommand(1, 2*nb, 2*i);
+ if ( !command(cmd) ) return false;
+ QValueVector<uint> read;
+ if ( !receiveWords(1, 1, read) ) return false;
+ for (uint k=0; k<nb; k++) {
+ uint index = i + start + k;
+ data[index]= read[5 + 2*k] & 0xFF | (read[6 + 2*k] << 8);
+ if ( vdata && index>=0x1000 && index<0x3FF0 && data[index]!=(*vdata)[index] ) {
+ log(Log::LineType::Error, i18n("Firmware memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).")
+ .arg(QString(toHex(index/2, device->nbCharsAddress())))
+ .arg(QString(toHex(data[index], device->nbCharsWord(Pic::MemoryRangeType::Code))))
+ .arg(QString(toHex((*vdata)[index], device->nbCharsWord(Pic::MemoryRangeType::Code)))));
+ return false;
+ }
+ }
+ }
+ monitor.addTaskProgress(data.count());
+ return true;
+}
+
+bool Pickit2::USBPort::eraseFirmwareCodeMemory()
+{
+ log(Log::DebugLevel::Normal, " Erase pickit2 firmware");
+ Pickit::Array cmd = createCommand(3, 0xC0, 0x2000);
+ if ( !command(cmd) ) return false; // erase 0x2000-0x4FFF
+ Port::usleep(1000000);
+ cmd = createCommand(3, 0xC0, 0x5000);
+ if ( !command(cmd) ) return false; // erase 0x5000-0x7FFF
+ Port::usleep(1000000);
+ return true;
+}
+
+bool Pickit2::USBPort::writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor)
+{
+ log(Log::DebugLevel::Normal, " Write pickit2 firmware");
+ for (uint i=0x1000; i<data.count(); i+=16) { // 2 bytes/word and 32 bytes/command max
+ uint start = 0;
+ for (; start<16; start++) if ( data[i + start].isInitialized() ) break;
+ if ( start==16 ) continue;
+ uint end = 15;
+ for (; end>start; end--) if ( data[i + end].isInitialized() ) break;
+ uint nb = end - start + 1;
+ Pickit::Array cmd = createCommand(2, 2*nb, 2*i);
+ for (uint k=0; k<nb; k++) {
+ cmd[5 + 2*k] = data[i + start + k].byte(0);
+ cmd[6 + 2*k] = data[i + start + k].byte(1);
+ }
+ if ( !command(cmd) ) return false;
+ Port::usleep(100000);
+ }
+ monitor.addTaskProgress(data.count());
+ Device::Array read;
+ if ( !readFirmwareCodeMemory(read, &data, monitor) ) return false;
+ log(Log::DebugLevel::Normal, " Write pickit2 firmware-loaded key");
+ Pickit::Array cmd = createCommand(2, 2, 0x7FFE);
+ cmd[5] = 0x55;
+ cmd[6] = 0x55;
+ return command(cmd);
+}
+
+bool Pickit2::USBPort::uploadFirmware(const Pic::Memory &memory, ProgressMonitor &monitor)
+{
+ if ( !eraseFirmwareCodeMemory() ) return false;
+ Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Code);
+ return writeFirmwareCodeMemory(data, monitor);
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::Hardware::readVoltages(VoltagesData &voltages)
+{
+ log(Log::DebugLevel::Extra, QString("readVoltages: Firmware is %1").arg(_base.firmwareVersion().pretty()));
+ if ( _base.firmwareVersion()<VersionData(1, 20, 0) ) {
+ log(Log::LineType::Warning, i18n("Cannot read voltages with this firmware version."));
+ return true;
+ }
+ if ( !port().command('M') ) return false;
+ Array a;
+ if ( !port().receive(a) ) return false;
+ voltages[Pic::TargetVdd].value = double(a[1] + a[2]*256) * 5.0 / 65535;
+ voltages[Pic::TargetVpp].value = double(a[3] + a[4]*256) * (5.0 /65535) * (7.4 / 2.7);
+ voltages[Pic::TargetVdd].error = ( a[0] & 0x08 );
+ voltages[Pic::TargetVpp].error = ( a[0] & 0x10 );
+ return true;
+}
+
+bool Pickit2::Hardware::setVddVpp(double vdd, double vpp)
+{
+ log(Log::DebugLevel::Extra, QString("setVddVpp: Firmware is %1").arg(_base.firmwareVersion().pretty()));
+ if ( _base.firmwareVersion()<VersionData(1, 20, 0) ) return true;
+ log(Log::DebugLevel::Normal, QString(" set Vdd = %1 V and Vpp = %2 V").arg(vdd).arg(vpp));
+ Array cmd;
+ cmd[0] = 's';
+ uint cvdd = uint(32.0 * vdd + 12.5);
+ cvdd <<= 6;
+ cmd[1] = cvdd & 0xC0;
+ cmd[2] = cvdd >> 8;
+ uint cvpp = uint(18.61 * vpp);
+ cmd[3] = 0x40;
+ cmd[4] = cvpp;
+ cmd[5] = uchar(4.5 * (cvdd >> 8)); // linit to 75% of vdd
+ cmd[6] = uchar(0.75 * cvpp); // linit to 75% of vpp
+ if ( !port().command(cmd) ) return false;
+ // wait until vpp is stabilized
+ for (uint i=0; i<30; i++) {
+ Port::usleep(50000);
+ VoltagesData voltages;
+ if ( !readVoltages(voltages) ) return false;
+ if ( voltages[Pic::TargetVpp].value<(vpp+0.5) ) break;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::Baseline::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x08; // Begin Programming externally timed
+ cmd[9] = 0x0E; // End externally time programming cycle
+ cmd[10] = 0x09; // Bulk Erase program memory
+ cmd[11] = 0x0B; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::P16F::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x18; // Begin Programming externally timed
+ cmd[9] = 0x0A; // End externally time programming cycle
+ cmd[10] = 0x09; // Bulk Erase program memory
+ cmd[11] = 0x0B; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::P16F87XA::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x18; // Begin Programming externally timed
+ cmd[9] = 0x17; // End externally time programming cycle
+ cmd[10] = 0x1F; // Bulk Erase program memory
+ cmd[11] = 0x1F; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::P16F7X::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x08; // Begin Programming externally timed
+ cmd[9] = 0x0E; // End externally time programming cycle
+ cmd[10] = 0x09; // Bulk Erase program memory
+ cmd[11] = 0x0B; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+bool Pickit2::P16F716::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x18; // Begin Programming externally timed
+ cmd[9] = 0x0E; // End externally time programming cycle
+ cmd[10] = 0x09; // Bulk Erase program memory
+ cmd[11] = 0x0B; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+//-----------------------------------------------------------------------------
+bool Pickit2::P18F::init()
+{
+ Array cmd;
+ cmd[0] = 'c';
+ cmd[1] = 0x00; // Load Configuration
+ cmd[2] = 0x02; // Load Program latches
+ cmd[3] = 0x03; // Load Data latches
+ cmd[4] = 0x04; // Read Program memory
+ cmd[5] = 0x05; // Read Data latches
+ cmd[6] = 0x06; // Increment Address
+ cmd[7] = 0x08; // Begin programming internally timed
+ cmd[8] = 0x18; // Begin Programming externally timed
+ cmd[9] = 0x0A; // End externally time programming cycle
+ cmd[10] = 0x09; // Bulk Erase program memory
+ cmd[11] = 0x0B; // Bulk Erase Data memory
+ cmd[12] = 0xFF; // Read Program memory
+ cmd[13] = 0xFF; // Read Data latches
+ cmd[14] = 0xFF; // Increment Address
+ cmd[15] = 0xFF; // Begin programming internally timed
+ return hardware().port().command(cmd);
+}
+
+bool Pickit2::P18F::doEraseCommand(uint cmd1, uint cmd2)
+{
+ Array cmd;
+ cmd[0] = 0x85;
+ cmd[1] = cmd1;
+ cmd[2] = cmd2;
+ return hardware().port().command(cmd);
+}
+
+bool Pickit2::P18F::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x84, 0x00);
+ Q_ASSERT( type==Pic::MemoryRangeType::Code );
+ if ( !doEraseCommand(0x81, 0x00) ) return false; // boot
+ for (uint i=0; i<device().config().protection().nbBlocks(); i++)
+ if ( !doEraseCommand(1 << i, 0x80) ) return false;
+ return true;
+}
+
+bool Pickit2::P18F::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ USBPort &port = static_cast<USBPort &>(hardware().port());
+ data.resize(device().nbWords(type));
+ QValueVector<uint> words;
+ switch (type.type()) {
+ case Pic::MemoryRangeType::DeviceId:
+ case Pic::MemoryRangeType::UserId:
+ case Pic::MemoryRangeType::Config: {
+ Pickit::Array cmd = port.createCommand(0x80, data.count(), device().range(type).start.toUInt());
+ if ( !port.command(cmd) ) return false;
+ if ( !hardware().port().receiveWords(1, 1, words) ) return false;
+ for (uint k=0; k<data.count(); k++) {
+ data[k] = words[k];
+ if ( vdata && !hardware().verifyWord(k, data[k], type, *vdata) ) return false;
+ }
+ return true;
+ }
+ case Pic::MemoryRangeType::Code:
+ for (uint i=0; i<data.count();) {
+ Array cmd;
+ for (uint k=0; k<8; k++) port.fillCommand(cmd, 0x80, 64, 2*(i + 32 * k), 5*k);
+ if ( !port.command(cmd) ) return false;
+ for (uint k=0; k<8; k++) {
+ if ( !hardware().port().receiveWords(2, 1, words) ) return false;
+ for (uint k=0; k<32; k++) {
+ data[i] = words[k];
+ if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
+ i++;
+ }
+ }
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+ case Pic::MemoryRangeType::Eeprom:
+ for (uint i=0; i<data.count();) {
+ Pickit::Array cmd = port.createCommand(0x81, 64, i, false);
+ if ( !port.command(cmd) ) return false;
+ if ( !hardware().port().receiveWords(1, 1, words) ) return false;
+ for (uint k=0; k<64; k++) {
+ data[i] = words[k];
+ if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
+ i++;
+ }
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::CalBackup:
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+bool Pickit2::P18F::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ Q_UNUSED(force);
+ USBPort &port = static_cast<USBPort &>(hardware().port());
+ switch (type.type()) {
+ case Pic::MemoryRangeType::UserId: {
+ Pickit::Array cmd = port.createCommand(0x82, data.count() / 2, device().range(type).start.toUInt());
+ for (uint i=0; i<data.count(); i++) cmd[i + 5] = data[i].byte(0);
+ return port.command(cmd);
+ }
+ case Pic::MemoryRangeType::Config: {
+ Array cmd;
+ for (uint i=0; i<data.count()/2; i++) {
+ cmd[4*i] = 0x84;
+ cmd[1 + 4*i] = 2*i;
+ cmd[2 + 4*i] = data[2*i].byte(0);
+ cmd[3 + 4*i] = data[2*i+1].byte(0);
+ }
+ return port.command(cmd);
+ }
+ case Pic::MemoryRangeType::Code: {
+ uint nb = Pickit2::data(device().name()).progWidth;
+ for (uint i=0; i<data.count();) {
+ bool allBlank = true;
+ Pickit::Array cmd = port.createCommand(0x82, nb, 2*i);
+ for (uint k=0; k<nb; k++) {
+ if ( data[i].byte(0)!=0xFF || data[i].byte(1)!=0xFF ) allBlank = false;
+ cmd[5 + 2*k] = data[i].byte(0);
+ cmd[6 + 2*k] = data[i].byte(1);
+ i++;
+ }
+ if ( !allBlank && !port.command(cmd) ) return false;
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+ }
+ case Pic::MemoryRangeType::Eeprom:
+ for (uint i=0; i<data.count();) {
+ bool allBlank = true;
+ Pickit::Array cmd = port.createCommand(0x87, 32, i, false);
+ for (uint k=0; k<32; k++) {
+ if ( data[i].byte(0)!=0xFF ) allBlank = false;
+ cmd[4+k] = data[i].byte(0);
+ i++;
+ }
+ if ( !allBlank && !port.command(cmd) ) return false;
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+ case Pic::MemoryRangeType::DeviceId:
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::CalBackup:
+ case Pic::MemoryRangeType::DebugVector:
+ case Pic::MemoryRangeType::HardwareStack:
+ case Pic::MemoryRangeType::ProgramExecutive:
+ case Pic::MemoryRangeType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+bool Pickit2::P18F2X20::doEraseCommand(uint cmd1)
+{
+ Array cmd;
+ cmd[0] = 0x86;
+ cmd[1] = cmd1;
+ return hardware().port().command(cmd);
+}
+
+bool Pickit2::P18F2X20::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x81);
+ Q_ASSERT( type==Pic::MemoryRangeType::Code );
+ if ( !doEraseCommand(0x83) ) return false; // boot
+ for (uint i=0; i<device().config().protection().nbBlocks(); i++)
+ if ( !doEraseCommand(0x88 + i) ) return false;
+ return true;
+}
diff --git a/src/progs/pickit2/base/pickit2.h b/src/progs/pickit2/base/pickit2.h
new file mode 100644
index 0000000..8efa8ff
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PICKIT2_H
+#define PICKIT2_H
+
+#include "pickit.h"
+#include "pickit2_data.h"
+
+namespace Pickit2
+{
+//-----------------------------------------------------------------------------
+class Array : public Pickit::Array
+{
+public:
+ Array() : Pickit::Array(64, 'Z', PrintAlphaNum) {}
+};
+
+//-----------------------------------------------------------------------------
+class USBPort : public Pickit::USBPort
+{
+public:
+ USBPort(Log::Base &log) : Pickit::USBPort(0x0033, log) {}
+ virtual Pickit::Array array() const { return Array(); }
+ void fillCommand(Pickit::Array &cmd1, uchar cmd2, uint nbBytes, uint address, uint i, bool longAddress = true) const;
+ Pickit::Array createCommand(uchar cmd, uint nbBytes, uint address, bool longAddress = true) const;
+
+ bool readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor);
+ //bool readFirmwareEepromMemory(Device::Array &data);
+ bool eraseFirmwareCodeMemory();
+ bool writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor);
+ //bool writeFirmwareEepromMemory(const Device::Array &data);
+ bool resetFirmwareDevice(::Programmer::Mode mode) { return command(mode==::Programmer::BootloadMode ? 'B' : 0xFF); }
+ bool uploadFirmware(const Pic::Memory &memory, ProgressMonitor &monitor);
+
+private:
+ virtual uint readEndPoint() const { return 0x81; }
+ virtual uint writeEndPoint() const { return 0x01; }
+};
+
+//-----------------------------------------------------------------------------
+class Hardware : public Pickit::Hardware
+{
+public:
+ Hardware(::Programmer::Base &base) : Pickit::Hardware(base, new USBPort(base)) {}
+ virtual bool readVoltages(VoltagesData &voltages);
+ bool setVddVpp(double vdd, double vpp);
+};
+
+//-----------------------------------------------------------------------------
+class Baseline : public Pickit::Baseline
+{
+public:
+ Baseline(::Programmer::Base &base) : Pickit::Baseline(base) {}
+ virtual bool init();
+ virtual char entryMode() const { return data(device().name()).entryMode; }
+ virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Eeprom ? 4 : 16); }
+};
+
+//-----------------------------------------------------------------------------
+class P16F : public Pickit::P16F
+{
+public:
+ P16F(::Programmer::Base &base) : Pickit::P16F(base) {}
+ virtual bool init();
+ virtual char entryMode() const { return data(device().name()).entryMode; }
+ virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Code ? 16 : 4); }
+};
+
+class P16F87XA : public P16F
+{
+public:
+ P16F87XA(::Programmer::Base &base) : P16F(base) {}
+ virtual bool init();
+};
+
+class P16F7X : public P16F
+{
+public:
+ P16F7X(::Programmer::Base &base) : P16F(base) {}
+ virtual bool init();
+ virtual char writeCode() const { return 'w'; }
+};
+
+class P16F716 : public P16F
+{
+public:
+ P16F716(::Programmer::Base &base) : P16F(base) {}
+ virtual bool init();
+};
+
+//-----------------------------------------------------------------------------
+class P18F : public Pickit::DeviceSpecific
+{
+public:
+ P18F(::Programmer::Base &base) : Pickit::DeviceSpecific(base) {}
+ Hardware &hardware() { return static_cast<Hardware &>(Pickit::DeviceSpecific::hardware()); }
+ virtual bool init();
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool) { return doEraseCommand(0x87, 0x0F); }
+ bool doEraseCommand(uint cmd1, uint cmd2);
+ virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata);
+ virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force);
+ virtual char entryMode() const { return data(device().name()).entryMode; }
+};
+
+class P18F2X20 : public P18F
+{
+public:
+ P18F2X20(::Programmer::Base &base) : P18F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool) { return doEraseCommand(0x80); }
+ bool doEraseCommand(uint cmd);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/pickit2/base/pickit2.xml b/src/progs/pickit2/base/pickit2.xml
new file mode 100644
index 0000000..044b7bc
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2.xml
@@ -0,0 +1,114 @@
+<!-- ************************************************************************* -->
+<!-- * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> * -->
+<!-- * * -->
+<!-- * This program is free software; you can redistribute it and/or modify * -->
+<!-- * it under the terms of the GNU General Public License as published by * -->
+<!-- * the Free Software Foundation; either version 2 of the License, or * -->
+<!-- * (at your option) any later version. * -->
+<!-- *************************************************************************/-->
+<!DOCTYPE piklab>
+
+<type name="pickit2">
+ <device name="10F200" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="10F202" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="10F204" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="10F206" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="10F220" family="Baseline" entry="O" pmode="0" />
+ <device name="10F222" family="Baseline" entry="O" pmode="0" />
+ <device name="12F508" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="12F509" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="12F510" family="Baseline" entry="O" pmode="0" support_type="tested" />
+ <device name="16F505" family="Baseline" entry="O" pmode="0" />
+ <device name="16F506" family="Baseline" entry="O" pmode="0" />
+ <device name="16F54" family="Baseline" entry="O" pmode="0" />
+ <device name="16F57" family="Baseline" entry="O" pmode="0" />
+ <device name="16F59" family="Baseline" entry="O" pmode="0" />
+
+ <device name="12F615" family="P16F" entry="P" pmode="n" pwidth="1" support_type="tested" />
+ <device name="12F629" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" />
+ <device name="12F635" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="12F675" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" />
+ <device name="12F683" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F616" family="P16F" entry="P" pmode="n" pwidth="4" support_type="tested" />
+ <device name="16F627A" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F628A" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F630" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" />
+ <device name="16F631" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F636" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F639" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F648A" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F676" family="P16F" entry="P" pmode="1" regen="true" support_type="tested" />
+ <device name="16F677" family="P16F" entry="P" pmode="1" support_type="tested" />
+ <device name="16F684" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F685" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F687" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F688" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F689" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F690" family="P16F" entry="P" pmode="4" support_type="tested" />
+ <device name="16F716" family="P16F716" entry="O" pmode="4" />
+ <device name="16F73" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F74" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F76" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F77" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F737" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F747" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F767" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F777" family="P16F7X" entry="O" pmode="n" pwidth="2" />
+ <device name="16F785" family="P16F" entry="P" pmode="4" />
+ <device name="16F818" family="P16F87XA" entry="O" pmode="n" pwidth="4" support_type="tested" />
+ <device name="16F819" family="P16F87XA" entry="O" pmode="n" pwidth="4" support_type="tested" />
+ <device name="16F87" family="P16F87XA" entry="O" pmode="n" pwidth="4" />
+ <device name="16F88" family="P16F87XA" entry="O" pmode="n" pwidth="4" />
+ <device name="16F873" family="P16F" entry="O" pmode="n" pwidth="8" />
+ <device name="16F874" family="P16F" entry="O" pmode="n" pwidth="8" />
+ <device name="16F876" family="P16F" entry="O" pmode="n" pwidth="8" />
+ <device name="16F877" family="P16F" entry="O" pmode="n" pwidth="8" />
+ <device name="16F873A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F874A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F876A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F877A" family="P16F87XA" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F913" family="P16F" entry="O" pmode="n" pwidth="4" support_type="tested" />
+ <device name="16F914" family="P16F" entry="O" pmode="n" pwidth="4" support_type="tested" />
+ <device name="16F916" family="P16F" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F917" family="P16F" entry="O" pmode="n" pwidth="8" support_type="tested" />
+ <device name="16F946" family="P16F" entry="O" pmode="n" pwidth="8" />
+
+ <device name="18F1220" family="P18F2X20" entry="O" pmode="n" pwidth="4" />
+ <device name="18F1320" family="P18F2X20" entry="O" pmode="n" pwidth="4" />
+ <device name="18F2220" family="P18F2X20" entry="P" pmode="n" pwidth="4" />
+ <device name="18F2221" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2320" family="P18F2X20" entry="P" pmode="n" pwidth="4" />
+ <device name="18F2321" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2410" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2420" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2455" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2480" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2510" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2515" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2520" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2525" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2550" family="P18F" entry="P" pmode="n" pwidth="16" support_type="tested" />
+ <device name="18F2580" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2585" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2610" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2620" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F2680" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4220" family="P18F2X20" entry="P" pmode="n" pwidth="4" />
+ <device name="18F4221" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4320" family="P18F2X20" entry="P" pmode="n" pwidth="4" />
+ <device name="18F4321" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4410" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4420" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4455" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4480" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4510" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4515" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4520" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4525" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4550" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4580" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4585" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4610" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4620" family="P18F" entry="P" pmode="n" pwidth="16" />
+ <device name="18F4680" family="P18F" entry="P" pmode="n" pwidth="16" />
+</type>
diff --git a/src/progs/pickit2/base/pickit2_data.h b/src/progs/pickit2/base/pickit2_data.h
new file mode 100644
index 0000000..abae867
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2_data.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PICKIT2_DATA_H
+#define PICKIT2_DATA_H
+
+#include <qstring.h>
+
+namespace Pickit2
+{
+ struct Data {
+ char entryMode, progMode;
+ uchar progWidth;
+ bool regenerateOsccal;
+ };
+ extern const Data &data(const QString &device);
+} // namespace
+
+#endif
diff --git a/src/progs/pickit2/base/pickit2_prog.cpp b/src/progs/pickit2/base/pickit2_prog.cpp
new file mode 100644
index 0000000..88b73b9
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2_prog.cpp
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pickit2_prog.h"
+
+#include "devices/list/device_list.h"
+#include "pickit2.h"
+
+//----------------------------------------------------------------------------
+VersionData Pickit2::Base::firmwareVersion(Programmer::FirmwareVersionType type) const
+{
+ switch (type.type()) {
+ case Programmer::FirmwareVersionType::Min: return VersionData(1, 10, 0);
+ case Programmer::FirmwareVersionType::Recommended:
+ case Programmer::FirmwareVersionType::Max: return VersionData(1, 20, 0);
+ case Programmer::FirmwareVersionType::Nb_Types: break;
+ }
+ Q_ASSERT(false);
+ return VersionData();
+}
+
+bool Pickit2::Base::deviceHasOsccalRegeneration() const
+{
+ return data(device()->name()).regenerateOsccal;
+}
+
+bool Pickit2::Base::setTarget()
+{
+ // #### FIXME: this needs to test for 18J first to protected them
+ if ( !static_cast<Pickit2::Hardware &>(hardware()).setVddVpp(5.0, 12.0) ) return false;
+ return static_cast<Pickit::DeviceSpecific *>(_specific)->init();
+}
+
+bool Pickit2::Base::internalEnterMode(::Programmer::Mode mode)
+{
+ USBPort &port = static_cast<USBPort &>(hardware().port());
+ if ( !port.resetFirmwareDevice(mode) ) return false;
+ log(Log::DebugLevel::Extra, "disconnecting and try to reconnect PICkit2 in new mode...");
+ disconnectHardware();
+ Port::usleep(3000000);
+ return connectHardware();
+}
+
+bool Pickit2::Base::doUploadFirmware(PURL::File &file)
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Device::lister().data("18F2550"));
+ Pic::Memory memory(static_cast<const Pic::Data &>(data));
+ QStringList errors, warnings;
+ Pic::Memory::WarningTypes warningTypes;
+ if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) {
+ log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\" (%2).").arg(file.url().pretty()).arg(errors[0]));
+ return false;
+ }
+ if ( warningTypes!=Pic::Memory::NoWarning ) {
+ log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 18F2550 inside PICkit2."));
+ return false;
+ }
+ log(Log::LineType::Information, i18n(" Uploading PICkit2 firmware..."));
+ if ( !enterMode(::Programmer::BootloadMode) ) return false;
+ _progressMonitor.insertTask(i18n("Uploading Firmware..."), 2*data.nbWords(Pic::MemoryRangeType::Code));
+ if ( !static_cast<USBPort &>(hardware().port()).uploadFirmware(memory, _progressMonitor) ) {
+ log(Log::LineType::Error, i18n("Failed to upload firmware."));
+ return false;
+ }
+ log(Log::LineType::Information, i18n("Firmware succesfully uploaded."));
+ return enterMode(::Programmer::NormalMode);
+}
+
+//----------------------------------------------------------------------------
+Programmer::Hardware *Pickit2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const
+{
+ return new Hardware(base);
+}
diff --git a/src/progs/pickit2/base/pickit2_prog.h b/src/progs/pickit2/base/pickit2_prog.h
new file mode 100644
index 0000000..5a67e2a
--- /dev/null
+++ b/src/progs/pickit2/base/pickit2_prog.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PICKIT2_PROG_H
+#define PICKIT2_PROG_H
+
+#include "common/global/global.h"
+#include "pickit_prog.h"
+
+namespace Pickit2
+{
+//----------------------------------------------------------------------------
+class Base : public Pickit::Base
+{
+Q_OBJECT
+public:
+ Base(const Programmer::Group &group, const Pic::Data *data) : Pickit::Base(group, data) {}
+ virtual bool deviceHasOsccalRegeneration() const;
+ virtual bool setTarget();
+
+private:
+ virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const;
+ virtual bool internalEnterMode(::Programmer::Mode mode);
+ virtual bool doUploadFirmware(PURL::File &file);
+};
+
+//----------------------------------------------------------------------------
+class Group : public Pickit::Group
+{
+public:
+ virtual QString name() const { return "pickit2"; }
+ virtual QString label() const { return i18n("PICkit2 Firmware 1.x"); }
+ virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; }
+ virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); }
+
+protected:
+ virtual void initSupported();
+ virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit2::Base(*this, static_cast<const Pic::Data *>(data)); }
+ virtual Programmer::Hardware *createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const;
+ virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const;
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/pickit2/base/pickit_prog.cpp b/src/progs/pickit2/base/pickit_prog.cpp
new file mode 100644
index 0000000..c11dd08
--- /dev/null
+++ b/src/progs/pickit2/base/pickit_prog.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pickit_prog.h"
+
+#include "common/global/global.h"
+#include "pickit.h"
+#include "progs/base/prog_config.h"
+
+Pickit::Base::Base(const Programmer::Group &group, const Pic::Data *data)
+ : ::Programmer::PicBase(group, data, "pickit_programmer")
+{}
+
+Pickit::Hardware &Pickit::Base::hardware()
+{
+ return static_cast<Hardware &>(*_hardware);
+}
+
+bool Pickit::Base::readFirmwareVersion()
+{
+ return hardware().port().getMode(_firmwareVersion, _mode);
+}
+
+bool Pickit::Base::regenerateOsccal(const PURL::Url &url)
+{
+ log(Log::DebugLevel::Normal, QString(" Calibration firmware file: %1").arg(url.pretty()));
+ Log::StringView sview;
+ PURL::File file(url, sview);
+ if ( !file.openForRead() ) {
+ log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty()));
+ return false;
+ }
+ Pic::Memory memory(*device());
+ QStringList errors, warnings;
+ Pic::Memory::WarningTypes warningTypes;
+ if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) {
+ log(Log::LineType::Error, i18n("Could not read calibration firmware file \"%1\" (%2).").arg(url.pretty()).arg(errors[0]));
+ return false;
+ }
+ if ( warningTypes!=Pic::Memory::NoWarning ) {
+ log(Log::LineType::Error, i18n("Calibration firmware file seems incompatible with selected device %1.").arg(device()->name()));
+ return false;
+ }
+ if ( !askContinue(i18n("This will overwrite the device code memory. Continue anyway?")) ) return false;
+ if ( !program(memory, Pic::MemoryRange(Pic::MemoryRangeType::Nb_Types)) ) return false;
+ Device::Array array(1);
+ if ( !static_cast<Hardware &>(hardware()).regenerateOsccal(array[0]) ) return false;
+ return programCalibration(array);
+}
diff --git a/src/progs/pickit2/base/pickit_prog.h b/src/progs/pickit2/base/pickit_prog.h
new file mode 100644
index 0000000..b35fc92
--- /dev/null
+++ b/src/progs/pickit2/base/pickit_prog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PICKIT_PROG_H
+#define PICKIT_PROG_H
+
+#include "common/global/global.h"
+#include "progs/icd2/base/microchip.h"
+#include "progs/base/prog_group.h"
+#include "pickit.h"
+
+namespace Pickit
+{
+class Hardware;
+
+//----------------------------------------------------------------------------
+class Base : public Programmer::PicBase
+{
+Q_OBJECT
+public:
+ Base(const Programmer::Group &group, const Pic::Data *data);
+ virtual bool deviceHasOsccalRegeneration() const = 0;
+ bool regenerateOsccal(const PURL::Url &url);
+ virtual bool readFirmwareVersion();
+
+protected:
+ Hardware &hardware();
+};
+
+//----------------------------------------------------------------------------
+class Group : public Programmer::PicGroup
+{
+public:
+ virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; }
+ virtual bool isPortSupported(PortType type) const { return ( type==PortType::USB ); }
+};
+
+} // namespace
+
+#endif