diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 18:42:24 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 18:42:24 +0000 |
commit | f508189682b6fba62e08feeb1596f682bad5fff9 (patch) | |
tree | 28aeb0e6c19386c385c1ce5edf8a92c1bca15281 /src/progs/pickit2/base | |
download | piklab-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.am | 12 | ||||
-rw-r--r-- | src/progs/pickit2/base/base.pro | 6 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit.cpp | 337 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit.h | 137 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2.cpp | 447 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2.h | 123 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2.xml | 114 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2_data.h | 24 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2_prog.cpp | 78 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit2_prog.h | 50 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit_prog.cpp | 54 | ||||
-rw-r--r-- | src/progs/pickit2/base/pickit_prog.h | 45 |
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 |