summaryrefslogtreecommitdiffstats
path: root/src/progs/direct
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/direct
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/direct')
-rw-r--r--src/progs/direct/Makefile.am3
-rw-r--r--src/progs/direct/base/Makefile.am13
-rw-r--r--src/progs/direct/base/base.pro10
-rw-r--r--src/progs/direct/base/direct.cpp394
-rw-r--r--src/progs/direct/base/direct.h90
-rw-r--r--src/progs/direct/base/direct.xml291
-rw-r--r--src/progs/direct/base/direct_16.cpp150
-rw-r--r--src/progs/direct/base/direct_16.h46
-rw-r--r--src/progs/direct/base/direct_16F.cpp275
-rw-r--r--src/progs/direct/base/direct_16F.h162
-rw-r--r--src/progs/direct/base/direct_18.cpp109
-rw-r--r--src/progs/direct/base/direct_18.h34
-rw-r--r--src/progs/direct/base/direct_18F.cpp318
-rw-r--r--src/progs/direct/base/direct_18F.h107
-rw-r--r--src/progs/direct/base/direct_30.cpp261
-rw-r--r--src/progs/direct/base/direct_30.h44
-rw-r--r--src/progs/direct/base/direct_baseline.cpp88
-rw-r--r--src/progs/direct/base/direct_baseline.h68
-rw-r--r--src/progs/direct/base/direct_data.h21
-rw-r--r--src/progs/direct/base/direct_mem24.cpp207
-rw-r--r--src/progs/direct/base/direct_mem24.h47
-rw-r--r--src/progs/direct/base/direct_pic.cpp187
-rw-r--r--src/progs/direct/base/direct_pic.h68
-rw-r--r--src/progs/direct/base/direct_prog.cpp62
-rw-r--r--src/progs/direct/base/direct_prog.h74
-rw-r--r--src/progs/direct/base/direct_prog_config.cpp145
-rw-r--r--src/progs/direct/base/direct_prog_config.h42
-rw-r--r--src/progs/direct/direct.pro2
-rw-r--r--src/progs/direct/gui/Makefile.am5
-rw-r--r--src/progs/direct/gui/direct_config_widget.cpp249
-rw-r--r--src/progs/direct/gui/direct_config_widget.h74
-rw-r--r--src/progs/direct/xml/Makefile.am14
-rw-r--r--src/progs/direct/xml/xml.pro17
-rw-r--r--src/progs/direct/xml/xml_direct_parser.cpp60
34 files changed, 3737 insertions, 0 deletions
diff --git a/src/progs/direct/Makefile.am b/src/progs/direct/Makefile.am
new file mode 100644
index 0000000..fccf96d
--- /dev/null
+++ b/src/progs/direct/Makefile.am
@@ -0,0 +1,3 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+SUBDIRS = xml base gui
diff --git a/src/progs/direct/base/Makefile.am b/src/progs/direct/base/Makefile.am
new file mode 100644
index 0000000..99070fe
--- /dev/null
+++ b/src/progs/direct/base/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libdirectprog.la
+libdirectprog_la_SOURCES = direct_pic.cpp direct_baseline.cpp direct_16.cpp \
+ direct_16F.cpp direct_18.cpp direct_18F.cpp direct_prog.cpp direct_prog_config.cpp \
+ direct_data.cpp direct_mem24.cpp direct.cpp
+libdirectprog_la_DEPENDENCIES = direct_data.cpp
+
+noinst_DATA = direct.xml
+direct_data.cpp: ../xml/xml_direct_parser direct.xml
+ ../xml/xml_direct_parser
+CLEANFILES = direct_data.cpp
diff --git a/src/progs/direct/base/base.pro b/src/progs/direct/base/base.pro
new file mode 100644
index 0000000..97253b4
--- /dev/null
+++ b/src/progs/direct/base/base.pro
@@ -0,0 +1,10 @@
+STOPDIR = ../../../..
+include($${STOPDIR}/lib.pro)
+
+TARGET = directprog
+HEADERS += direct.h direct_data.h direct_pic.h direct_mem24.h direct_prog.h \
+ direct_prog_config.h direct_baseline.h direct_16.h direct_16F.h \
+ direct_18.h direct_18F.h
+SOURCES += direct.cpp direct_data.cpp direct_pic.cpp direct_mem24.cpp direct_prog.cpp \
+ direct_prog_config.cpp direct_baseline.cpp direct_16.cpp direct_16F.cpp \
+ direct_18.cpp direct_18F.cpp
diff --git a/src/progs/direct/base/direct.cpp b/src/progs/direct/base/direct.cpp
new file mode 100644
index 0000000..fc53cf3
--- /dev/null
+++ b/src/progs/direct/base/direct.cpp
@@ -0,0 +1,394 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * Copyright (C) Brian C. Lane *
+ * *
+ * 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 "direct.h"
+
+#include <iostream>
+
+#include "common/port/parallel.h"
+#include "common/port/serial.h"
+#include "progs/base/generic_prog.h"
+#include "direct_prog_config.h"
+
+using namespace std;
+
+//-----------------------------------------------------------------------------
+const Direct::PinData Direct::PIN_DATA[Nb_PinTypes] = {
+ { I18N_NOOP("MCLR (Vpp)"), "0 V", "13 V", "vpp",
+ I18N_NOOP("The VPP pin is used to select the high voltage programming mode."),
+ Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") },
+ { I18N_NOOP("Power (Vdd)"), "0 V", "5 V", "vdd",
+ I18N_NOOP("The VDD pin is used to apply 5V to the programmed device.\nMust be set to GND if your programmer doesn't control the VDD line."),
+ Port::Out, true, I18N_NOOP("Check this box to turn voltage on/off for this pin.") },
+ { I18N_NOOP("Clock"), "0 V", "5 V", "clock",
+ I18N_NOOP("The CLOCK pin is used to synchronize serial data of the DATA IN and DATA OUT pins."),
+ Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") },
+ { I18N_NOOP("Data Out"), "0 V", "5 V", "datao",
+ I18N_NOOP("The DATA OUT pin is used to send data to the programmed device."),
+ Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") },
+ { I18N_NOOP("Data In"), "0 V", "5 V", "datai",
+ I18N_NOOP("The DATA IN pin is used to receive data from the programmed device."),
+ Port::In, false, I18N_NOOP("This pin is driven by the programmed device.\nWithout device, it must follow the \"Data out\" pin (when powered on).") },
+ { I18N_NOOP("Data R/W"), "Data in", "Data out", "drw",
+ I18N_NOOP("The DATA RW pin selects the direction of data buffer.\nMust be set to GND if your programmer does not use bi-directionnal buffer."),
+ Port::Out, true, I18N_NOOP("Check this box to change DATA buffer direction.") }
+};
+
+//-----------------------------------------------------------------------------
+namespace Direct
+{
+class SerialPort : public Port::Serial
+{
+public:
+ SerialPort(const QString &device, Log::Base &base)
+ : Serial(device, NeedBreak, base) {}
+
+ bool open() {
+ if ( !Port::Serial::open() ) return false;
+ if ( !setMode(IgnoreBreak | IgnoreParity, ByteSize8 | EnableReceiver | IgnoreControlLines, S9600, 0) ) return false;
+ // set up lines for "idle state" ???
+ return true;
+ }
+};
+} // namespace
+
+//-----------------------------------------------------------------------------
+Direct::Hardware::Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data)
+ : ::Programmer::PicHardware(base, port, data.name), _data(data.data)
+{}
+
+bool Direct::Hardware::internalConnectHardware()
+{
+ if ( !_port->open() ) return false;
+
+ // keep the safe state of rw (read)...
+ setPin(DataOut, Low);
+ setPin(Clock, Low);
+ setPin(Vpp, Off);
+ setPin(Vdd, Off);
+ setRead();
+
+ return true;
+}
+
+void Direct::Hardware::setPin(PinType type, bool on)
+{
+ int pin = _data.pins[type];
+ if ( isGroundPin(pin) ) return;
+ uint p = (pin<0 ? -pin : pin)-1;
+ //log(Log::DebugLevel::Extra, QString("Hardware::setPin %1 %2: %3 %4").arg(PIN_DATA[type].label).arg(pin).arg(on).arg(_data.clockDelay));
+ _port->setPinOn(p, on, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic));
+ if ( type==Clock ) Port::usleep(_data.clockDelay);
+}
+
+bool Direct::Hardware::readBit()
+{
+ int pin = _data.pins[DataIn];
+ Q_ASSERT( pin!=0 );
+ uint p = (pin<0 ? -pin : pin)-1;
+ bool on;
+ _port->readPin(p, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic), on);
+ //log(Log::DebugLevel::Extra, QString("Hardware::read DataIn %2: %3").arg(pin).arg(on));
+ return on;
+}
+
+uint Direct::Hardware::nbPins(Port::IODir dir) const
+{
+ return _port->pinData(dir).count();
+}
+
+QString Direct::Hardware::pinLabelForIndex(Port::IODir dir, uint i) const
+{
+ Port::PinData pd = _port->pinData(dir)[i];
+ return QString("%1 (%2)").arg(pd.pin+1).arg(pd.label);
+}
+
+Port::IODir Direct::Hardware::ioTypeForPin(int pin) const
+{
+ if ( isGroundPin(pin) ) return Port::NoIO;
+ uint p = (pin<0 ? -pin : pin)-1;
+ return _port->ioDir(p);
+}
+
+uint Direct::Hardware::pinForIndex(Port::IODir dir, uint i) const
+{
+ Q_ASSERT( i<=uint(_port->pinData(dir).count()) );
+ if ( i==uint(_port->pinData(dir).count()) ) return _port->groundPin()+1;
+ return _port->pinData(dir)[i].pin+1;
+}
+
+uint Direct::Hardware::indexForPin(Port::IODir dir, int pin) const
+{
+ QValueVector<Port::PinData> v = _port->pinData(dir);
+ Q_ASSERT( pin!=0 );
+ uint p = (pin<0 ? -pin : pin)-1;
+ for (uint i=0; i<uint(v.count()); i++)
+ if ( v[i].pin==p ) return i;
+ Q_ASSERT( isGroundPin(pin) );
+ return v.count();
+}
+
+bool Direct::Hardware::isGroundPin(int pin) const
+{
+ Q_ASSERT( pin!=0 );
+ uint p = (pin<0 ? -pin : pin)-1;
+ return _port->isGroundPin(p);
+}
+
+bool Direct::operator !=(const HData &d1, const HData &d2)
+{
+ for (uint i=0; i<Nb_PinTypes; i++)
+ if ( d1.pins[i]!=d2.pins[i] ) return true;
+ if ( d1.clockDelay!=d2.clockDelay ) return true;
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+Direct::SerialHardware::SerialHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data)
+ : Hardware(base, new SerialPort(portDevice, base), data)
+{}
+
+Direct::ParallelHardware::ParallelHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data)
+ : Hardware(base, new Port::Parallel(portDevice, base), data)
+{}
+
+/*
+//-----------------------------------------------------------------------------
+int Direct::Hardware::hardware_test()
+{
+ char t[80] ;
+
+ cout << endl << "Please execute this Direct::Hardware test without any PIC"
+ " connected to your programmer" <<endl << endl ;
+
+ do
+ {
+ cout << "Ready for tests ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ if( t[0] == 'n') return -1 ;
+
+
+ // stage 1 - hard initialization
+ // setpins("parallel","/dev/parport0", -5, -4, 3, 2, 10) ;
+
+ //Default RW line not used...
+ HData data = { { 3, 5, 7, 4, 8, 0 }, 0 };
+ Log::ConsoleView view;
+ Direct::Programmer programmer;
+ programmer.setView(&view);
+ SerialHardware hw(programmer, "/dev/ttyS0", data);
+ if ( !hw.connectHardware() ) {
+ cout << "Direct::Hardware initialization error" <<endl ;
+ return 1 ;
+ }
+
+
+ //++Mirko!!
+ //By Ciri 11/3/2004...
+ //From here to the end of function i haven't modified nothing...
+ //--Mirko!!
+
+ // stage 2 - all lines off
+ hw.setPin(Vpp, Off);
+ hw.setPin(Vdd, Off);
+ hw.setPin(Clock, Low);
+ hw.setPin(DataOut, Low);
+ cout << "All the following lines must be 0V : " << endl <<
+ "16F84 pin 13 (data out)"<<endl <<
+ "16F84 pin 12 (clock)"<<endl <<
+ "16F84 pin 14 (VDD=power)"<<endl <<
+ "16F84 pin 4 (VPP=prog)"<<endl ;
+ do
+ {
+ cout << "OK ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+
+ if( t[0] == 'n') return 2 ;
+
+ // stage 3 - data out check
+ hw.setPin(DataOut, High);
+ cout << "16F84 pin 13 (data out) must be 5V"<<endl ;
+ do
+ {
+ cout << "OK ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ hw.setPin(DataOut, Low);
+
+ if( t[0] == 'n') return 3 ;
+
+ // stage 4 - clock check
+ hw.setPin(Clock, High);
+ cout << "16F84 pin 12 (clock) must be 5V"<<endl ;
+ do
+ {
+ cout << "OK ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ hw.setPin(Clock, Low);
+
+ if( t[0] == 'n') return 4 ;
+
+ // stage 5 - VDD check
+ hw.setPin(Vdd, On);
+ cout << "16F84 pin 14 (power) must be 5V"<<endl ;
+ do
+ {
+ cout << "OK ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ hw.setPin(Vdd, Off) ;
+
+ if( t[0] == 'n') return 5 ;
+
+ // stage 6 - VPP check
+ hw.setPin(Vpp, On);
+ cout << "16F84 pin 4 (VDD) must be between 13V and 14V"<<endl ;
+ do
+ {
+ cout << "OK ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ hw.setPin(Vpp , Off);
+
+ if( t[0] == 'n') return 6 ;
+
+ // stage 7 - test input data
+ // set data out hi, because bi-directionnal
+ // on pin 13 uses the open collector capability of 7407
+ hw.setPin(DataOut, High);
+ int in = hw.readBit();
+ if( !in )
+ {
+ cout << "DataIn error (16F84 pin 13) : must be 5V and is not" << endl ;
+ return 7 ;
+ }
+ cout << "Please set 16F84 pin 13 (DataIn) low " <<
+ "(connect it to 16F84 pin 5 - GND)" << endl ;
+ do
+ {
+ cout << "Done ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+
+ in = hw.readBit();
+ if(in )
+ {
+ cout << "DataIn error (pin 13) : must be 0V and is not" << endl ;
+ return 7 ;
+ }
+
+ cout << "Congratulations! - Direct::Hardware is OK." <<endl ;
+ return 0 ;
+}
+
+// this is my specific speed test
+int Direct::Hardware::timing_test()
+{
+ char t[80] ;
+ int cmd ;
+ long loop = 50000000 ;
+
+ cout << endl << "Please execute this Direct::Hardware test without any PIC"
+ " connected to your programmer" <<endl << endl ;
+
+ do
+ {
+ cout << "Ready for tests ? (y/n) " ;
+ cin >> t ;
+ } while(t[0] != 'y' && t[0] != 'n') ;
+ if( t[0] == 'n') return -1 ;
+
+
+ // stage 1 - hard initialization
+ //Default Line RW not used...
+ HData data = { { -5, -4, 3, 2, 10, 25 }, 0 };
+ Log::ConsoleView view;
+ Log::Manager manager;
+ manager.setView(&view);
+ ParallelHardware hw("/dev/parport0", manager, data);
+ if ( !hw.connectHardware() ) {
+ cout << "Direct::Hardware initialization error" <<endl ;
+ return 1 ;
+ }
+
+ //++Mirko!!
+ //By Ciri 11/3/2004...
+ //From here to the end of function i have modified nothing...
+ //--Mirko!!
+
+ // stage 2 - all lines off
+ hw.setPin(Vpp, Off);
+ hw.setPin(Vdd, Off);
+ hw.setPin(Clock, Low);
+ hw.setPin(DataOut, Low);
+
+ // stage 3 - choose test
+ cout << "Remember : " << endl <<
+ "16F84 pin 5 is GND"<<endl <<
+ "16F84 pin 13 is data-out"<<endl <<
+ "16F84 pin 12 is clock"<<endl ;
+
+ cout << loop << " periods test .... " << endl ;
+
+ cout << "1 - Maximum speed clock " << endl <<
+ "2 - 100us half period "<<endl <<
+ "3 - load data 0x2AAA (programmer->chip)"<<endl <<
+ "4 - end"<<endl ;
+ do
+ {
+ cout << "CMD (1-4)>> " ;
+ cin >> cmd ;
+ } while(cmd < 1 || cmd > 4) ;
+
+ if(cmd == 4) return 2 ;
+ else if ( cmd == 1)
+ {
+ for(long j=0 ; j < loop ; ++j)
+ {
+ hw.setPin(Clock, Low);
+ hw.setPin(Clock, High);
+ }
+ }
+
+ else if ( cmd == 2)
+ {
+ for(long j=0 ; j < loop ; ++j)
+ {
+ hw.setPin(Clock, Low);
+ Port::usleep(100);
+ hw.setPin(Clock, High);
+ Port::usleep(100);
+ }
+ }
+
+ else if ( cmd == 3) {
+ for (long j=0; j<loop; ++j)
+ {
+ int d = 0x2AAA ;
+ d &= 0x3FFF ; // mask unused msb
+ d <<= 1; // insert start bit
+
+ for (uint x = 0; x<16; x++) {
+ hw.setPin(Clock, High);
+ if ( d & 0x01 ) hw.setPin(DataOut, High);
+ else hw.setPin(DataOut, Low);
+ hw.setPin(Clock, Low);
+ d >>= 1;
+ }
+ hw.setPin(DataOut, High);
+ }
+ }
+
+ return 0;
+}
+*/
diff --git a/src/progs/direct/base/direct.h b/src/progs/direct/base/direct.h
new file mode 100644
index 0000000..6a890b0
--- /dev/null
+++ b/src/progs/direct/base/direct.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * Copyright (C) Brian C. Lane *
+ * *
+ * 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 DIRECT_H
+#define DIRECT_H
+
+#include "devices/pic/prog/pic_prog.h"
+
+namespace Direct
+{
+enum State { Low = 0, High = 1, Off = Low, On = High };
+enum PinType { Vpp = 0, Vdd, Clock, DataOut, DataIn, DataRW, Nb_PinTypes };
+struct PinData {
+ const char *label, *offLabel, *onLabel, *key, *comment;
+ Port::IODir dir;
+ bool canBeGround;
+ const char *testComment;
+};
+extern const PinData PIN_DATA[Nb_PinTypes];
+
+//-----------------------------------------------------------------------------
+class HardwareData;
+enum Type { Normal, EPEToolkitMK3 };
+struct HData
+{
+ int pins[Nb_PinTypes];
+ uint clockDelay;
+ Type type;
+};
+
+class Hardware : public ::Programmer::PicHardware
+{
+public:
+ static Hardware *create(Port::Base *port, const Device::Data &device, const HData &data);
+
+public:
+ Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data);
+ bool readBit();
+ void setPin(PinType type, bool on);
+ void setRead() { setPin(DataRW, true); }
+ void setWrite() { setPin(DataRW, false); }
+
+ uint nbPins(Port::IODir dir) const;
+ QString pinLabelForIndex(Port::IODir dir, uint i) const;
+ Port::IODir ioTypeForPin(int pin) const;
+ uint pinForIndex(Port::IODir dir, uint i) const;
+ uint indexForPin(Port::IODir dir, int pin) const;
+ bool isGroundPin(int pin) const;
+ Type type() const { return _data.type; }
+
+ // hardware test --- please use it for a newly
+ // designed/constructed programmer board
+ // because pin assignation is hard coded in this
+ // routine, you might have to edit it. ++Gib:
+ //static int hardware_test();
+ // timing test --- please use it to ensure that
+ // the program meets the timing specifications
+ //static int timing_test();
+
+private:
+ HData _data;
+
+ virtual bool internalConnectHardware();
+
+ friend class Programmer;
+};
+extern bool operator !=(const HData &d1, const HData &d2);
+
+class SerialHardware : public Hardware
+{
+public:
+ SerialHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data);
+};
+
+class ParallelHardware : public Hardware
+{
+public:
+ ParallelHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct.xml b/src/progs/direct/base/direct.xml
new file mode 100644
index 0000000..4997450
--- /dev/null
+++ b/src/progs/direct/base/direct.xml
@@ -0,0 +1,291 @@
+<!-- ************************************************************************* -->
+<!-- * 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="direct">
+ <device name="10F200" family="10F2XX" support_type="tested" />
+ <device name="10F202" family="10F2XX" support_type="tested" />
+ <device name="10F204" family="10F2XX" support_type="tested" />
+ <device name="10F206" family="10F2XX" support_type="tested" />
+ <device name="10F220" family="10F2XX" />
+ <device name="10F222" family="10F2XX" />
+ <device name="12F508" family="10F2XX" support_type="tested" />
+ <device name="12F509" family="10F2XX" support_type="tested" />
+ <device name="12F510" family="10F2XX" support_type="tested" />
+
+ <device name="12C508" family="12C5XX" />
+ <device name="12C508A" family="12C5XX" />
+ <device name="12C509" family="12C5XX" />
+ <device name="12C509A" family="12C5XX" />
+ <device name="12CE518" family="12C5XX" />
+ <device name="12CE519" family="12C5XX" />
+ <device name="12CR509A" family="12C5XX" />
+
+ <device name="12C671" family="12C67X" />
+ <device name="12C672" family="12C67X" />
+ <device name="12CE673" family="12C67X" />
+ <device name="12CE674" family="12C67X" />
+
+ <device name="12F629" family="12F675" />
+ <device name="12F675" family="12F675" support_type="tested" />
+
+ <device name="12F635" family="12F6XX_16F6XX" />
+ <device name="12F683" family="12F6XX_16F6XX" />
+
+ <device name="14000" family="12C67X" />
+
+ <device name="16C432" family="12C67X" />
+ <device name="16C433" family="12C67X" />
+
+ <device name="16C505" family="12C5XX" />
+
+ <device name="16C554" family="12C67X" />
+ <device name="16C557" family="12C67X" />
+ <device name="16C558" family="12C67X" />
+
+ <device name="16C52" family="12C5XX" />
+ <device name="16C54" family="12C5XX" />
+ <device name="16C54A" family="12C5XX" />
+ <device name="16C54B" family="12C5XX" />
+ <device name="16C54C" family="12C5XX" />
+ <device name="16CR54A" family="12C5XX" />
+ <device name="16CR54B" family="12C5XX" />
+ <device name="16CR54C" family="12C5XX" />
+ <device name="16C55" family="12C5XX" />
+ <device name="16C55A" family="12C5XX" />
+ <device name="16C56" family="12C5XX" />
+ <device name="16C56A" family="12C5XX" />
+ <device name="16CR56A" family="12C5XX" />
+ <device name="16C57" family="12C5XX" />
+ <device name="16C57C" family="12C5XX" />
+ <device name="16CR57B" family="12C5XX" />
+ <device name="16CR57C" family="12C5XX" />
+ <device name="16C58A" family="12C5XX" />
+ <device name="16C58B" family="12C5XX" />
+ <device name="16CR58A" family="12C5XX" />
+ <device name="16CR58B" family="12C5XX" />
+
+ <device name="16C61" family="12C67X" />
+ <device name="16C62" family="12C67X" />
+ <device name="16C620" family="12C67X" />
+ <device name="16C620A" family="12C67X" />
+ <device name="16C621" family="12C67X" />
+ <device name="16C621A" family="12C67X" />
+ <device name="16C622" family="12C67X" />
+ <device name="16C622A" family="12C67X" />
+ <device name="16C62A" family="12C67X" />
+ <device name="16C62B" family="12C67X" />
+ <device name="16C63" family="12C67X" />
+ <device name="16C63A" family="12C67X" />
+ <device name="16C64" family="12C67X" />
+ <device name="16C64A" family="12C67X" />
+ <device name="16C65" family="12C67X" />
+ <device name="16C65A" family="12C67X" />
+ <device name="16C65B" family="12C67X" />
+ <device name="16C66" family="12C67X" />
+ <device name="16C67" family="12C67X" />
+ <device name="16C71" family="12C67X" />
+ <device name="16C710" family="12C67X" />
+ <device name="16C711" family="12C67X" />
+ <device name="16C712" family="12C67X" />
+ <device name="16C715" family="12C67X" />
+ <device name="16C716" family="12C67X" />
+ <device name="16C72" family="12C67X" />
+ <device name="16CR72" family="12C67X" />
+ <device name="16C72A" family="12C67X" />
+ <device name="16C73" family="12C67X" />
+ <device name="16C73A" family="12C67X" />
+ <device name="16C73B" family="12C67X" />
+ <device name="16C74" family="12C67X" />
+ <device name="16C745" family="12C67X" />
+ <device name="16C74A" family="12C67X" />
+ <device name="16C74B" family="12C67X" />
+ <device name="16C76" family="12C67X" />
+ <device name="16C765" family="12C67X" />
+ <device name="16C77" family="12C67X" />
+ <device name="16C773" family="12C67X" />
+ <device name="16C774" family="12C67X" />
+ <device name="16C923" family="12C67X" />
+ <device name="16C924" family="12C67X" />
+ <device name="16C925" family="12C67X" />
+ <device name="16C926" family="12C67X" />
+ <device name="16CE623" family="12C67X" />
+ <device name="16CE624" family="12C67X" />
+ <device name="16CE625" family="12C67X" />
+ <device name="16CR62" family="12C67X" />
+ <device name="16CR620A" family="12C67X" />
+ <device name="16CR63" family="12C67X" />
+ <device name="16CR64" family="12C67X" />
+ <device name="16CR65" family="12C67X" />
+ <device name="16C642" family="12C67X" />
+ <device name="16C662" family="12C67X" />
+ <device name="16C717" family="12C67X" />
+ <device name="16C770" family="12C67X" />
+ <device name="16C771" family="12C67X" />
+ <device name="16C781" family="12C67X" />
+ <device name="16C782" family="12C67X" />
+
+ <device name="16F54" family="10F2XX" />
+ <device name="16F57" family="16F57" />
+ <device name="16F59" family="16F57" />
+ <device name="16F505" family="10F2XX" />
+ <device name="16F506" family="10F2XX" />
+
+ <device name="16C84" family="16CR8X" />
+ <device name="16CR83" family="16CR8X" />
+ <device name="16CR84" family="16CR8X" />
+ <device name="16F627" family="16F62X" />
+ <device name="16F627A" family="16F62XA" />
+ <device name="16F628" family="16F62X" />
+ <device name="16F628A" family="16F62XA" />
+ <device name="16F630" family="12F675" />
+
+ <device name="16F636" family="12F6XX_16F6XX" />
+ <device name="16F639" family="12F6XX_16F6XX" />
+ <device name="16F648A" family="16F62XA" />
+ <device name="16F676" family="12F675" />
+ <device name="16F684" family="12F6XX_16F6XX" />
+ <device name="16F685" family="12F6XX_16F6XX" />
+ <device name="16F687" family="12F6XX_16F6XX" />
+ <device name="16F688" family="12F6XX_16F6XX" />
+ <device name="16F689" family="12F6XX_16F6XX" />
+ <device name="16F690" family="12F6XX_16F6XX" />
+ <device name="16F716" family="12C67X" />
+ <device name="16F73" family="16F7X" />
+ <device name="16F74" family="16F7X" />
+ <device name="16F76" family="16F7X" />
+ <device name="16F77" family="16F7X" />
+ <device name="16F737" family="16F7X" support_type="tested" />
+ <device name="16F747" family="16F7X" support_type="tested" />
+ <device name="16F767" family="16F7X" support_type="tested" />
+ <device name="16F777" family="16F7X" support_type="tested" />
+ <device name="16F785" family="16F913" />
+ <device name="16F818" family="16F81X" />
+ <device name="16F819" family="16F81X" />
+ <device name="16F83" family="16F8X" />
+ <device name="16F84" family="16F8X" />
+ <device name="16F84A" family="16F84A" />
+ <device name="16F87" family="16F81X" />
+ <device name="16F870" family="16F87X" />
+ <device name="16F871" family="16F87X" support_type="tested" />
+ <device name="16F872" family="16F87X" support_type="tested" />
+ <device name="16F873" family="16F87X" support_type="tested" />
+ <device name="16F873A" family="16F87XA" />
+ <device name="16F874" family="16F87X" support_type="tested" />
+ <device name="16F874A" family="16F87XA" />
+ <device name="16F876" family="16F87X" support_type="tested" />
+ <device name="16F876A" family="16F87XA" />
+ <device name="16F877" family="16F87X" support_type="tested" />
+ <device name="16F877A" family="16F87XA" />
+ <device name="16F88" family="16F81X" />
+ <device name="16F913" family="16F913" />
+ <device name="16F914" family="16F913" />
+ <device name="16F916" family="16F916" />
+ <device name="16F917" family="16F916" />
+ <device name="16F946" family="16F916" />
+
+ <device name="18F1220" family="18F1220" support_type="tested" />
+ <device name="18F1320" family="18F1220" support_type="tested" />
+ <device name="18F2220" family="18F1220" support_type="tested" />
+ <device name="18F2320" family="18F1220" support_type="tested" />
+ <device name="18F4220" family="18F1220" support_type="tested" />
+ <device name="18F4320" family="18F1220" support_type="tested" />
+
+ <device name="18F242" family="18F242" support_type="tested" />
+ <device name="18F248" family="18F242" support_type="tested" />
+ <device name="18F252" family="18F242" support_type="tested" />
+ <device name="18F258" family="18F242" support_type="tested" />
+ <device name="18F442" family="18F242" support_type="tested" />
+ <device name="18F448" family="18F242" support_type="tested" />
+ <device name="18F452" family="18F242" support_type="tested" />
+ <device name="18F458" family="18F242" support_type="tested" />
+
+ <device name="18F1230" family="18F2221" />
+ <device name="18F1330" family="18F2221" />
+ <device name="18F2221" family="18F2221" />
+ <device name="18F2321" family="18F2221" />
+ <device name="18F4221" family="18F2221" />
+ <device name="18F4321" family="18F2221" />
+ <device name="18F2410" family="18F2221" />
+ <device name="18F2510" family="18F2221" />
+ <device name="18F4410" family="18F2221" />
+ <device name="18F4510" family="18F2221" />
+ <device name="18F2420" family="18F2221" />
+ <device name="18F2520" family="18F2221" />
+ <device name="18F4420" family="18F2221" />
+ <device name="18F4520" family="18F2221" />
+ <device name="18F2480" family="18F2221" />
+ <device name="18F2580" family="18F2221" />
+ <device name="18F4480" family="18F2221" />
+ <device name="18F4580" family="18F2221" />
+ <device name="18F2455" family="18F2221" support_type="tested" />
+ <device name="18F2450" family="18F2221" />
+ <device name="18F2550" family="18F2221" />
+ <device name="18F4455" family="18F2221" />
+ <device name="18F4450" family="18F2221" />
+ <device name="18F4550" family="18F2221" support_type="tested" />
+ <device name="18F2515" family="18F2221" />
+ <device name="18F2525" family="18F2221" />
+ <device name="18F2610" family="18F2221" />
+ <device name="18F2620" family="18F2221" />
+ <device name="18F4515" family="18F2221" />
+ <device name="18F4525" family="18F2221" />
+ <device name="18F4610" family="18F2221" />
+ <device name="18F4620" family="18F2221" />
+ <device name="18F2585" family="18F2221" />
+ <device name="18F2680" family="18F2221" />
+ <device name="18F4585" family="18F2221" />
+ <device name="18F4680" family="18F2221" />
+ <device name="18F2682" family="18F2221" />
+ <device name="18F4682" family="18F2221" />
+ <device name="18F2685" family="18F2221" />
+ <device name="18F4685" family="18F2221" />
+
+ <device name="18F6525" family="18F242" />
+ <device name="18F6621" family="18F242" />
+ <device name="18F8525" family="18F242" />
+ <device name="18F8621" family="18F242" />
+ <device name="18F2331" family="18F242" />
+ <device name="18F2431" family="18F242" />
+ <device name="18F4331" family="18F242" />
+ <device name="18F4431" family="18F242" />
+ <device name="18F6585" family="18F242" />
+ <device name="18F6680" family="18F242" />
+ <device name="18F8585" family="18F242" />
+ <device name="18F8680" family="18F242" />
+ <device name="18F6520" family="18F242" />
+ <device name="18F6620" family="18F242" />
+ <device name="18F6720" family="18F242" />
+ <device name="18F8520" family="18F242" />
+ <device name="18F8620" family="18F242" />
+ <device name="18F8720" family="18F242" />
+
+ <device name="18F2439" family="18F2439" />
+ <device name="18F4439" family="18F2439" />
+ <device name="18F2539" family="18F2539" />
+ <device name="18F4539" family="18F2539" />
+
+ <device name="18F6310" family="18F6310" />
+ <device name="18F6410" family="18F6310" />
+ <device name="18F8310" family="18F6310" />
+ <device name="18F8410" family="18F6310" />
+ <device name="18F6390" family="18F6310" />
+ <device name="18F6490" family="18F6310" />
+ <device name="18F8390" family="18F6310" />
+ <device name="18F8490" family="18F6310" />
+
+ <device name="18F6527" family="18F6527" />
+ <device name="18F6622" family="18F6527" />
+ <device name="18F6627" family="18F6527" />
+ <device name="18F6722" family="18F6527" />
+ <device name="18F8527" family="18F6527" />
+ <device name="18F8622" family="18F6527" />
+ <device name="18F8627" family="18F6527" />
+ <device name="18F8722" family="18F6527" />
+</type>
diff --git a/src/progs/direct/base/direct_16.cpp b/src/progs/direct/base/direct_16.cpp
new file mode 100644
index 0000000..124b35e
--- /dev/null
+++ b/src/progs/direct/base/direct_16.cpp
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_16.h"
+
+#include "common/global/global.h"
+
+//----------------------------------------------------------------------------
+void Direct::pic16::send_bits(BitValue d, uint nbb)
+{
+ hardware().setWrite();
+ for (uint x = nbb; x; --x) {
+ hardware().setPin(Clock, High);
+ if ( d.bit(0) ) hardware().setPin(DataOut, High);
+ else hardware().setPin(DataOut, Low);
+ Port::usleep(1+_clockDelay);
+ hardware().setPin(Clock, Low);
+ Port::usleep(1+_clockDelay);
+ d >>= 1;
+ }
+ hardware().setPin(DataOut, High);
+ hardware().setRead();
+}
+
+void Direct::pic16::send_word(BitValue d)
+{
+ hardware().setWrite();
+ d <<= 1; // insert start bit
+ for (uint x = 0; x<16; x++) {
+ hardware().setPin(Clock, High);
+ if ( d.bit(0) ) hardware().setPin(DataOut, High);
+ else hardware().setPin(DataOut, Low);
+ Port::usleep(1+_clockDelay) ; // needed for slow programmers/fast PCs
+ hardware().setPin(Clock, Low);
+ Port::usleep(1+_clockDelay) ;
+ d >>= 1; // Move the data over 1 bit
+ }
+ hardware().setPin(DataOut, High); // Added for ITU-1 support
+ hardware().setRead();
+}
+
+// Read 14 bits of data from the PIC
+// clock idles low, change data. 1 start bit, 1 stop bit, data valid on falling edge.
+BitValue Direct::pic16::get_word()
+{
+ hardware().setRead();
+ BitValue ind = 0;
+ hardware().setPin(DataOut, High);
+ for (uint x = 16; x ; --x) {
+ hardware().setPin(Clock, High);
+ Port::usleep(1+_clockDelay);
+ if ( hardware().readBit() ) ind |= 0x8000;
+ else ind = ind.maskWith(0x7FFF);
+ ind >>= 1;
+ hardware().setPin(Clock, Low);
+ Port::usleep(1+_clockDelay);
+ }
+ return ind;
+}
+
+bool Direct::pic16::incrementPC(uint steps)
+{
+ for (uint i=0; i<steps; i++) pulseEngine("k6,");
+ return true;
+}
+
+BitValue Direct::pic16::readWord(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return pulseEngine("k5,r,");
+ return pulseEngine("k4,R,");
+}
+
+bool Direct::pic16::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ data.resize(device().nbWords(type));
+ gotoMemory(type);
+ uint nbWords = data.count();
+ bool only = false;
+ if (vdata) {
+ bool only = vdata->actions & ::Programmer::OnlyProgrammedVerify;
+ const Device::Array wdata = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type);
+ if (only) nbWords = findNonMaskEnd(type, wdata)+1;
+ }
+ BitValue mask = device().mask(type);
+ for (uint i = 0; i<nbWords; i++) {
+ if ( !only || data[i]!=mask || type!=Pic::MemoryRangeType::Code ) {
+ data[i] = readWord(type).maskWith(mask);
+ if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
+ }
+ incrementPC(1);
+ }
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom )
+ _base.progressMonitor().addTaskProgress(data.count());
+ return true;
+}
+
+bool Direct::pic16::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ gotoMemory(type);
+ for (uint i = 0; i<data.count(); ) {
+ if ( !writeWords(type, data, i, force) ) {
+ log(Log::LineType::Error, i18n("Error programming %1 at %2.").arg(type.label()).arg(toHexLabel(i, 8)));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Direct::pic16::skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force)
+{
+ if (force) return false;
+ uint nb = (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1);
+ for (uint k=0; k<nb; k++)
+ if ( data[i+k]!=device().mask(type) ) return false;
+ incrementPC(nb);
+ i += nb;
+ return true;
+}
+
+bool Direct::pic16::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom) pulseEngine("k3,S,", data[i]);
+ else {
+ uint nb = (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1);
+ for (uint k=0; k<nb; k++) {
+ if ( k!=0 ) incrementPC(1);
+ pulseEngine("k2,S,", data[i+k]);
+ }
+ }
+ startProg(type);
+ QString cmd = QString("w%1").arg(waitProgTime(type));
+ pulseEngine(cmd.latin1());
+ endProg(type);
+ return true;
+}
+
+bool Direct::pic16::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force)
+{
+ if ( skipMaskWords(type, data, i, force) ) return true;
+ if ( !writeWords(type, data, i) ) return false;
+ incrementPC(1);
+ i += (type==Pic::MemoryRangeType::Code ? nbWordsCodeProg() : 1);
+ return true;
+}
diff --git a/src/progs/direct/base/direct_16.h b/src/progs/direct/base/direct_16.h
new file mode 100644
index 0000000..683083e
--- /dev/null
+++ b/src/progs/direct/base/direct_16.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * 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 DIRECT_16_H
+#define DIRECT_16_H
+
+#include "direct_pic.h"
+
+namespace Direct
+{
+//----------------------------------------------------------------------------
+class pic16 : public Pic8DeviceSpecific
+{
+public:
+ pic16(::Programmer::Base &base) : Pic8DeviceSpecific(base) {}
+ virtual BitValue get_word();
+ virtual BitValue get_byte() { return get_word().maskWith(0xFF); }
+ virtual void send_word(BitValue word);
+ virtual void send_bits(BitValue d, uint nbBits);
+ virtual void send_cmd(BitValue d) { send_bits(d, 6); }
+ 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);
+
+protected:
+ virtual bool setPowerOn() { return setPowerOnVddFirst(); }
+ virtual bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force);
+ virtual bool incrementPC(uint steps);
+ virtual bool gotoMemory(Pic::MemoryRangeType type) = 0;
+ virtual uint nbWordsCodeProg() const { return 1; }
+ virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k8,"); }
+ virtual uint waitProgTime(Pic::MemoryRangeType type) const = 0;
+ virtual void endProg(Pic::MemoryRangeType) {}
+ virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force);
+ virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i);
+ virtual BitValue readWord(Pic::MemoryRangeType type);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_16F.cpp b/src/progs/direct/base/direct_16F.cpp
new file mode 100644
index 0000000..feeb185
--- /dev/null
+++ b/src/progs/direct/base/direct_16F.cpp
@@ -0,0 +1,275 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2004 Keith Baker <syzygy@pubnix.org> [16F7X] *
+ * *
+ * 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 "direct_16F.h"
+
+#include "common/global/global.h"
+
+//-----------------------------------------------------------------------------
+bool Direct::P16F::gotoTestMemory()
+{
+ pulseEngine("k0,S,", 0x3FFF); // PC set at 0x2000
+ return true;
+}
+
+bool Direct::P16F::gotoMemory(Pic::MemoryRangeType type)
+{
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Code: return true;
+ case Pic::MemoryRangeType::Eeprom: return true;
+ case Pic::MemoryRangeType::UserId: return gotoTestMemory();
+ case Pic::MemoryRangeType::DeviceId: return (gotoTestMemory() && incrementPC(6));
+ case Pic::MemoryRangeType::Config: return (gotoTestMemory() && incrementPC(7));
+ case Pic::MemoryRangeType::Cal:
+ if ( device().range(type).start==device().range(Pic::MemoryRangeType::Code).end+1 )
+ return incrementPC(device().range(type).start.toUInt());
+ return (gotoTestMemory() && incrementPC(8));
+ 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 Direct::P16F8X::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k2,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k3,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F8X::doErase(bool isProtected)
+{
+ if (isProtected) { // disable code protection + erase code and data
+ gotoMemory(Pic::MemoryRangeType::Config);
+ pulseEngine("k1,k7,k8,w10000,k1,k7");
+ } else {
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ }
+ doEmulatedEraseRange(Pic::MemoryRangeType::UserId);
+ doEmulatedEraseRange(Pic::MemoryRangeType::Config);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+uint Direct::P16F84A::waitProgTime(Pic::MemoryRangeType type) const
+{
+ if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::UserId ) return 4000 + 4000; // prog +erase
+ return 4000;
+}
+
+void Direct::P16F84A::startProg(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k24,");
+ else pulseEngine("k8,");
+}
+
+bool Direct::P16F84A::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k2,S,k9,k8,w10000", 0x3FFF); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k3,S,k11,k8,w10000", 0x3FFF); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F84A::doErase(bool isProtected)
+{
+ if (isProtected) { // disable code protection and erase
+ gotoMemory(Pic::MemoryRangeType::Config);
+ pulseEngine("k1,k7,k8,w10000,k1,k7");
+ } else {
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ }
+ doEmulatedEraseRange(Pic::MemoryRangeType::UserId);
+ doEmulatedEraseRange(Pic::MemoryRangeType::Config);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+uint Direct::P16F7X::waitProgTime(Pic::MemoryRangeType) const
+{
+ if ( device().name()=="16F72" ) return 3000;
+ return 1000;
+}
+
+bool Direct::P16F7X::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type!=Pic::MemoryRangeType::Code ) return false;
+ Device::Array array;
+ if ( !doRead(Pic::MemoryRangeType::Config, array, 0) ) return false;
+ pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet)
+ return doWrite(Pic::MemoryRangeType::Config, array, true);
+}
+
+bool Direct::P16F7X::doErase(bool)
+{
+ pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet)
+ return doEmulatedEraseRange(Pic::MemoryRangeType::UserId);
+}
+
+//-----------------------------------------------------------------------------
+// 16F628 seems to have problems with the standard 16F84 bulk
+// erase when disabling code protection : the data memory is not set to 0xFF.
+// This code adds a erase/programming pass on the data memory
+bool Direct::P16F62X::doErase(bool isProtected)
+{
+ P16F84A::doErase(isProtected);
+ if (isProtected) return doEmulatedEraseRange(Pic::MemoryRangeType::Eeprom);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P16F81X::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k9w2000"); // bulk erase code: 2ms
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k11w2000"); // bulk erase data: 2ms
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F81X::doErase(bool)
+{
+ pulseEngine("k31w8000"); // chip erase: 8ms
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+uint Direct::P12F675::waitProgTime(Pic::MemoryRangeType type) const
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return 6000;
+ return 2500;
+}
+
+bool Direct::P12F675::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k9,w9000"); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k11,w9000"); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P12F675::doErase(bool)
+{
+ pulseEngine("k0,S,", 0x3FFF);
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+uint Direct::P16F62XA::waitProgTime(Pic::MemoryRangeType type) const
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) return 6000;
+ return 2500;
+}
+
+bool Direct::P16F62XA::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k9,w12000"); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k11,w12000"); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F62XA::doErase(bool)
+{
+ pulseEngine("k0,S,w100", 0x3FFF);
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P16F87XA::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k9,w8000"); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k11,w8000"); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F87XA::doErase(bool)
+{
+ // I use the command 31 twice because, sometimes, the prog
+ // memory is not totally erased. Not very elegant, but it works.
+ pulseEngine("k0,S,k31w8000,k31w8000", 0x3FFF);
+ return doEmulatedEraseRange(Pic::MemoryRangeType::UserId);
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P16F913::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ pulseEngine("k9,w6000"); // bulk erase code
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k11,w6000"); // bulk erase data
+ return true;
+ }
+ return false;
+}
+
+bool Direct::P16F913::doErase(bool)
+{
+ // flow chart of figure 3.21 of prog sheet
+ doEraseRange(Pic::MemoryRangeType::Code);
+ pulseEngine("k0,S,", 0x3FFF);
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P16F785::doErase(bool)
+{
+ // flow chart of figure 3.20 of prog sheet
+ pulseEngine("k0,S,", 0x3FFF);
+ doEraseRange(Pic::MemoryRangeType::Code);
+ doEraseRange(Pic::MemoryRangeType::Eeprom);
+ return true;
+}
diff --git a/src/progs/direct/base/direct_16F.h b/src/progs/direct/base/direct_16F.h
new file mode 100644
index 0000000..0b0fca8
--- /dev/null
+++ b/src/progs/direct/base/direct_16F.h
@@ -0,0 +1,162 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2004 Keith Baker <syzygy@pubnix.org> [16F7X] *
+ * *
+ * 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 DIRECT_16F_HH
+#define DIRECT_16F_HH
+
+#include "direct_16.h"
+
+namespace Direct
+{
+//-----------------------------------------------------------------------------
+class P16F : public pic16
+{
+public:
+ P16F(::Programmer::Base &base) : pic16(base) {}
+ bool gotoTestMemory();
+ virtual bool gotoMemory(Pic::MemoryRangeType type);
+};
+
+//-----------------------------------------------------------------------------
+class P16F8X : public P16F
+{
+public:
+ P16F8X(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doErase(bool isProtected);
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 20000; }
+};
+
+//-----------------------------------------------------------------------------
+class P16CR8X : public P16F8X
+{
+public:
+ P16CR8X(::Programmer::Base &base) : P16F8X(base) {}
+ virtual bool doErase(bool) { return false; } // #### can't the eeprom be bulk erased ???
+ virtual bool doEraseRange(Pic::MemoryRangeType) { return false; }
+ // #### eeprom and config only can be programmed...
+};
+
+//-----------------------------------------------------------------------------
+class P16F84A : public P16F
+{
+public:
+ P16F84A(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual void startProg(Pic::MemoryRangeType type);
+ virtual uint waitProgTime(Pic::MemoryRangeType type) const;
+};
+
+typedef class P16F84A P16F87X;
+
+//-----------------------------------------------------------------------------
+class P16F7X : public P16F
+{
+public:
+ P16F7X(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ uint nbWordsCodeProg() const { return 2; }
+ virtual uint waitProgTime(Pic::MemoryRangeType type) const;
+ virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,"); }
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+//-----------------------------------------------------------------------------
+class P16F62X : public P16F84A
+{
+public:
+ P16F62X(::Programmer::Base &base) : P16F84A(base) {}
+ virtual bool doErase(bool isProtected);
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; }
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+//-----------------------------------------------------------------------------
+class P16F81X : public P16F
+{
+public:
+ P16F81X(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ uint nbWordsCodeProg() const { return 4; }
+ virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); }
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; }
+ virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k23,"); }
+};
+
+//-----------------------------------------------------------------------------
+class P12F675 : public P16F
+{
+public:
+ P12F675(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual uint waitProgTime(Pic::MemoryRangeType type) const;
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+//-----------------------------------------------------------------------------
+class P16F62XA : public P16F
+{
+public:
+ P16F62XA(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual uint waitProgTime(Pic::MemoryRangeType type) const;
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+//-----------------------------------------------------------------------------
+class P16F87XA : public P16F
+{
+public:
+ P16F87XA(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual uint nbWordsCodeProg() const { return 8; }
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; }
+};
+
+//-----------------------------------------------------------------------------
+class P16F913 : public P16F
+{
+public:
+ P16F913(::Programmer::Base &base) : P16F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual uint nbWordsCodeProg() const { return 4; }
+ virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); }
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2500; }
+ virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k10,w100"); }
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+class P16F916 : public P16F913
+{
+public:
+ P16F916(::Programmer::Base &base) : P16F913(base) {}
+ virtual uint nbWordsCodeProg() const { return 8; }
+};
+
+typedef class P16F913 P12F6XX_16F6XX;
+
+class P16F785 : public P16F913
+{
+public:
+ P16F785(::Programmer::Base &base) : P16F913(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_18.cpp b/src/progs/direct/base/direct_18.cpp
new file mode 100644
index 0000000..d512d32
--- /dev/null
+++ b/src/progs/direct/base/direct_18.cpp
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_18.h"
+
+// Commands specific to 18F:
+// xhh = send a 8 bits constant (hh must be a 2 digits hex constant)
+// Xhhhh = send a 16 bits constant (hhhh must be a 4 digits hex constant)
+bool Direct::P18::pulse(const char *&cmd, BitValue value, BitValue &res)
+{
+ switch (*cmd) {
+ case 'x': {
+ uint n;
+ sscanf(++cmd, "%02X", &n);
+ ++cmd;
+ log(Log::DebugLevel::Max, "SEND 1 byte constant : " + toHexLabel(n, 2));
+ send_bits(n, 8);
+ break;
+ }
+ case 'X': {
+ uint n;
+ sscanf(++cmd,"%04X", &n);
+ cmd += 3;
+ log(Log::DebugLevel::Max, "SEND 2 bytes constant : " + toHexLabel(n, 4));
+ send_bits(n, 16);
+ break;
+ }
+ default: return Pic8DeviceSpecific::pulse(cmd, value, res);
+ }
+ return true;
+}
+
+void Direct::P18::send_word(BitValue d)
+{
+ hardware().setWrite();
+ for (uint x = 0; x<16; x++) {
+ hardware().setPin(Clock, High);
+ if ( d.bit(0) ) hardware().setPin(DataOut, High);
+ else hardware().setPin(DataOut, Low);
+ Port::usleep(_clockDelay+5);
+ hardware().setPin(Clock, Low);
+ Port::usleep(_clockDelay+3);
+ d >>= 1; // Move the data over 1 bit
+ }
+ hardware().setPin(DataOut, High);
+ hardware().setRead();
+}
+
+BitValue Direct::P18::get_word()
+{
+ hardware().setRead();
+ BitValue ind = 0;
+ send_cmd(9);
+ hardware().setPin(DataOut, High);
+ for (uint x = 0; x<16; x++) {
+ hardware().setPin(Clock, High);
+ Port::usleep(_clockDelay+5);
+ if ( x>7 && hardware().readBit() ) ind |= (1 << x-8);
+ hardware().setPin(Clock, Low);
+ Port::usleep(_clockDelay+3);
+ }
+ send_cmd(9);
+ hardware().setPin(DataOut, High);
+ for (uint x = 0; x<16; x++) {
+ hardware().setPin(Clock, High);
+ Port::usleep(_clockDelay+5);
+ if ( x>7 && hardware().readBit() ) ind |= (1 << x);
+ hardware().setPin(Clock, Low);
+ Port::usleep(_clockDelay+3);
+ }
+ return ind;
+}
+
+BitValue Direct::P18::get_byte()
+{
+ hardware().setRead();
+ BitValue ind = 0;
+ send_cmd(2);
+ hardware().setPin(DataOut, High);
+ for (uint x = 0; x<16; x++) {
+ hardware().setPin(Clock, High);
+ Port::usleep(_clockDelay+5);
+ if ( x>7 && hardware().readBit() ) ind |= (1 << x-8);
+ hardware().setPin(Clock, Low);
+ Port::usleep(_clockDelay+3);
+ }
+ return ind;
+}
+
+void Direct::P18::send_bits(BitValue d, uint nbb)
+{
+ hardware().setWrite();
+ for (int x = nbb; x; --x) {
+ hardware().setPin(Clock, High);
+ if ( d.bit(0) ) hardware().setPin(DataOut, High);
+ else hardware().setPin(DataOut, Low);
+ Port::usleep(_clockDelay+5);
+ hardware().setPin(Clock, Low);
+ Port::usleep(_clockDelay+3);
+ d >>= 1; // Move the data over 1 bit
+ }
+ hardware().setPin(DataOut, High);
+ hardware().setRead();
+}
diff --git a/src/progs/direct/base/direct_18.h b/src/progs/direct/base/direct_18.h
new file mode 100644
index 0000000..6c2b4f3
--- /dev/null
+++ b/src/progs/direct/base/direct_18.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_18_HH
+#define DIRECT_18_HH
+
+#include "direct_pic.h"
+
+namespace Direct
+{
+
+class P18 : public Pic8DeviceSpecific
+{
+public:
+ P18(::Programmer::Base &base) : Pic8DeviceSpecific(base) {}
+ virtual bool setPowerOn() { return setPowerOnVddFirst(); }
+
+protected:
+ bool pulse(const char *&cmd, BitValue value, BitValue &res);
+ virtual void send_word(BitValue d);
+ virtual BitValue get_word();
+ virtual BitValue get_byte();
+ virtual void send_cmd(BitValue d) { send_bits(d, 4); }
+ virtual void send_bits(BitValue d, uint nbBits);
+};
+
+} //namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_18F.cpp b/src/progs/direct/base/direct_18F.cpp
new file mode 100644
index 0000000..9860e63
--- /dev/null
+++ b/src/progs/direct/base/direct_18F.cpp
@@ -0,0 +1,318 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_18F.h"
+
+#include "direct_data.h"
+
+//-----------------------------------------------------------------------------
+bool Direct::P18F::skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data,
+ uint &i, uint nb, bool forceProgram)
+{
+ if (forceProgram) return false;
+ for (uint k=0; k<nb; k++)
+ if ( data[i+k]!=device().mask(type) ) return false;
+ i += nb;
+ return true;
+}
+
+void Direct::P18F::program(Type type)
+{
+ QString cmd;
+ switch (type) {
+ case Code:
+ cmd = QString("d,C,c,C,c,C,c,Cw%1cw%2X0000,").arg(programHighTime(Code)).arg(programLowTime());
+ break;
+ case Erase:
+ pulseEngine("k0,X0000,"); // NOP
+ cmd = QString("k0;w%1;w%2;X0000").arg(programHighTime(type)).arg(programLowTime());
+ break;
+ case Eeprom:
+ for (;;) {
+ pulseEngine("k0,X50A6,");
+ pulseEngine("k0,X6EF5,");
+ pulseEngine("k0,X0000,"); // NOP
+ BitValue b = get_byte();
+ if ( !b.bit(1) ) break; // WR bit clear
+ }
+ cmd = QString("w%1").arg(programLowTime());
+ break;
+ }
+ pulseEngine(cmd);
+}
+
+void Direct::P18F::setCodePointer(uint address)
+{
+ pulseEngine("k0,S,k0,X6EF8,", 0x0E00 | ((address & 0xFF0000) >> 16));
+ pulseEngine("k0,S,k0,X6EF7,", 0x0E00 | ((address & 0x00FF00) >> 8));
+ pulseEngine("k0,S,k0,X6EF6,", 0x0E00 | (address & 0x0000FF));
+}
+
+void Direct::P18F::setPointer(Pic::MemoryRangeType type, uint offset)
+{
+ if ( type==Pic::MemoryRangeType::Eeprom ) {
+ pulseEngine("k0,S,k0,X6EA9,", 0x0E00 | (offset & 0x00FF));
+ pulseEngine("k0,S,k0,X6EAA,", 0x0E00 | ((offset & 0xFF00) >> 8));
+ } else setCodePointer(device().range(type).start.toUInt() + offset);
+}
+
+void Direct::P18F::directAccess(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::UserId || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9CA6"); // unset EECON1:CFGS
+ else pulseEngine("k0,X8CA6"); // set EECON1:CFGS
+ if ( type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9EA6"); // unset EECON1::EEPGD
+ else pulseEngine("k0,X8EA6"); // set EECON1::EEPGD
+}
+
+bool Direct::P18F::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ data.resize(device().nbWords(type));
+ uint offset = 0;
+ uint nbWords = data.count();
+ if (vdata) {
+ if ( vdata->actions & ::Programmer::OnlyProgrammedVerify ) {
+ const Device::Array wdata = static_cast<const Pic::Memory &>(vdata->memory).arrayForWriting(type);
+ offset = findNonMaskStart(type, wdata);
+ nbWords = findNonMaskEnd(type, wdata)+1;
+ }
+ }
+ BitValue mask = device().mask(type);
+ //qDebug("read %s %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, device().nbWords(type));
+ //pulseEngine("w300000"); // what for ?
+ directAccess(type);
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Eeprom:
+ for (uint i = 0; i<data.count(); i++) {
+ setPointer(type, i);
+ pulseEngine("k0,X80A6,k0,X50A8,k0,X6EF5,k0,X0000");
+ data[i] = pulseEngine("r").maskWith(mask);
+ if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false;
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ break;
+ case Pic::MemoryRangeType::Code:
+ setPointer(type, offset);
+ //pulseEngine("w1000"); ??
+ for (uint i=0; i<nbWords; i++) {
+ data[i] = pulseEngine("R").maskWith(mask);
+ if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false;
+ }
+ _base.progressMonitor().addTaskProgress(data.count());
+ break;
+ case Pic::MemoryRangeType::UserId:
+ case Pic::MemoryRangeType::Config:
+ case Pic::MemoryRangeType::DeviceId:
+ setPointer(type, 0);
+ for (uint i = 0; i<data.count(); i+=2) {
+ BitValue w = pulseEngine("R");
+ data[i] = w.maskWith(mask);
+ if ( vdata && !hardware().verifyWord(offset+i, data[i], type, *vdata) ) return false;
+ data[i+1] = w >> 8;
+ if ( vdata && !hardware().verifyWord(offset+i+1, data[i+1], type, *vdata) ) return false;
+ }
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ return true;
+}
+
+bool Direct::P18F::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ uint inc = device().addressIncrement(type);
+ //qDebug("write %s %i/%i %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, nbWords, data.count(), inc);
+ //pulseEngine("w300000"); ??
+ configureSinglePanel();
+ directAccess(type);
+ switch (type.type()) {
+ case Pic::MemoryRangeType::UserId: {
+ setPointer(type, 0);
+ Q_ASSERT( device().nbWords(Pic::MemoryRangeType::UserId)==8 );
+ uint i = 0;
+ for (uint k=0; k<4; k++) {
+ BitValue word = data[i] | data[i+1] << 8;
+ if ( (k+1)==4 ) pulseEngine("k15,S,", word);
+ else pulseEngine("k13,S,", word);
+ i += 2;
+ }
+ program(Code);
+ break;
+ }
+ case Pic::MemoryRangeType::Code: {
+ uint progWidth = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code);
+ for (uint i = 0; i<data.count(); ) {
+ if ( i!=0 && i%0x100==0 ) _base.progressMonitor().addTaskProgress(0x100);
+ if ( skipMaskWords(type, data, i, progWidth, force) ) continue;
+ setPointer(type, inc * i);
+ for (uint k=0; k<progWidth; k++) {
+ if ( (k+1)==progWidth ) pulseEngine("k15,S,", data[i]);
+ else pulseEngine("k13,S,", data[i]);
+ i++;
+ }
+ program(Code);
+ }
+ _base.progressMonitor().addTaskProgress(data.count()%0x100);
+ break;
+ }
+ case Pic::MemoryRangeType::Config:
+ pulseEngine("k0,XEF00,k0,XF800,"); // move PC somewhere else (0x100000)
+ for (uint i = 0; i<data.count(); i+=2) {
+ setPointer(type, inc * i);
+ BitValue w = data[i] | (data[i+1] << 8);
+ pulseEngine("k15,S,", w);
+ program(Code);
+ pulseEngine("k0,X2AF6,"); // increment address
+ pulseEngine("k15,S,", w);
+ program(Code);
+ pulseEngine("k0,X0000,"); // NOP: some devices need 4 NOPS here...
+ pulseEngine("k0,X0000,"); // NOP
+ pulseEngine("k0,X0000,"); // NOP
+ pulseEngine("k0,X0000,"); // NOP
+ }
+ break;
+ case Pic::MemoryRangeType::Eeprom:
+ for(uint i = 0; i<data.count(); ) {
+ if ( i!=0 && i%0x100==0 ) _base.progressMonitor().addTaskProgress(0x100);
+ if ( skipMaskWords(type, data, i, 1, force) ) continue;
+ setPointer(type, inc * i);
+ pulseEngine("k0,S,k0,X6EA8,", data[i] | 0x0E00); // load data
+ pulseEngine("k0,X84A6,"); // enable memory writes
+ unlockEeprom();
+ pulseEngine("k0,X82A6,"); // write
+ program(Eeprom);
+ pulseEngine("k0,X94A6,"); // disable writes
+ i++;
+ }
+ _base.progressMonitor().addTaskProgress(data.count()%0x100);
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ return true;
+}
+
+void Direct::P18F::unlockEeprom()
+{
+ pulseEngine("k0,X0E55,k0,X6EA7,k0,X0EAA,k0,X6EA7,");
+}
+
+bool Direct::P18F::doEraseCommand(uint cmd1, uint cmd2)
+{
+ if ( cmd1!=0 ) {
+ setCodePointer(0x3C0005);
+ pulseEngine("k12;X" + toHex(cmd1, 4));
+ }
+ setCodePointer(0x3C0004);
+ pulseEngine("k12;X" + toHex(cmd2, 4));
+ program(Erase);
+ return true;
+}
+
+bool Direct::P18F::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ doEraseCommand(0, 0x0083); // boot
+ for (uint i=0; i<device().config().protection().nbBlocks(); i++)
+ doEraseCommand(0, 0x0088 + i);
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0, 0x0081);
+ return false;
+}
+
+bool Direct::P18F::doErase(bool)
+{
+ return doEraseCommand(0, 0x0080);
+}
+
+//-----------------------------------------------------------------------------
+void Direct::P18F1220::program(Type type)
+{
+ if ( type==Eeprom ) {
+ pulseEngine("k0,X0000,"); // NOP
+ QString cmd = QString("k0;w%1;w%2;X0000").arg(programHighTime(type)).arg(programLowTime());
+ pulseEngine(cmd);
+ } else P18F::program(type);
+}
+
+//-----------------------------------------------------------------------------
+void Direct::P18F242::configureSinglePanel()
+{
+ setCodePointer(0x3C0006);
+ pulseEngine("k12,X0000");
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P18F2539::doErase(bool)
+{
+ // apparently there is no chip erase...
+ return ( doEraseRange(Pic::MemoryRangeType::Code) && doEraseRange(Pic::MemoryRangeType::Eeprom) );
+}
+
+bool Direct::P18F2539::doEraseCommand(uint cmd1, uint cmd2)
+{
+ Q_ASSERT( cmd1==0 );
+ setCodePointer(0x3C0004);
+ pulseEngine("k0;X" + toHex(cmd2, 4)); // is that correct ??
+ program(Erase);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P18F2439::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ configureSinglePanel();
+ directAccess(Pic::MemoryRangeType::Code);
+ for (uint i=0; i<40; i++) {
+ setCodePointer(0x200000 + 64*i);
+ pulseEngine("k0;X84A6;k0;X88A6"); // enable memory writes + setup erase
+ unlockEeprom();
+ pulseEngine("k0;X82A6"); // initiate erase
+ program(Erase);
+ pulseEngine("k0;X94A6"); // disable memory writes
+ }
+ return true;
+ }
+ return P18F2539::doEraseRange(type);
+}
+//-----------------------------------------------------------------------------
+bool Direct::P18F2221::doEraseRange(Pic::MemoryRangeType type)
+{
+ if ( type==Pic::MemoryRangeType::Code ) {
+ doEraseCommand(0, 0x8181); // boot
+ for (uint i=0; i<device().config().protection().nbBlocks(); i++) {
+ uint v = (1 << i);
+ doEraseCommand(v + v<<8, 0x8080);
+ }
+ return true;
+ }
+ if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0, 0x8484);
+ return false;
+}
+
+bool Direct::P18F2221::doErase(bool)
+{
+ return doEraseCommand(0x0F0F, 0x8787); // chip erase
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P18F6527::doErase(bool)
+{
+ return doEraseCommand(0xFFFF, 0x8787); // chip erase
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P18F6310::doErase(bool)
+{
+ setCodePointer(0x3C0005);
+ pulseEngine("k12,X010A");
+ setCodePointer(0x3C0004);
+ pulseEngine("k12,X018A");
+ program(Erase);
+ return true;
+}
diff --git a/src/progs/direct/base/direct_18F.h b/src/progs/direct/base/direct_18F.h
new file mode 100644
index 0000000..c3cbcf8
--- /dev/null
+++ b/src/progs/direct/base/direct_18F.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_18F_H
+#define DIRECT_18F_H
+
+#include "direct_18.h"
+
+namespace Direct
+{
+//-----------------------------------------------------------------------------
+class P18F : public P18
+{
+public:
+ P18F(::Programmer::Base &base) : P18(base) {}
+ virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata);
+ virtual bool doWrite(Pic::MemoryRangeType, const Device::Array &data, bool force);
+ virtual bool doEraseCommand(uint cmd1, uint cmd2);
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+
+ bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data,
+ uint &i, uint nb, bool force);
+ void setPointer(Pic::MemoryRangeType type, uint offset);
+ void setCodePointer(uint address);
+ enum Type { Code, Eeprom, Erase };
+ virtual void program(Type type);
+ virtual uint programHighTime(Type type) const { return (type==Code ? 1000 : 5000); }
+ virtual uint programLowTime() { return 5; }
+ virtual void configureSinglePanel() {}
+ virtual void unlockEeprom();
+ virtual void directAccess(Pic::MemoryRangeType type);
+};
+
+//-----------------------------------------------------------------------------
+class P18F1220 : public P18F
+{
+public:
+ P18F1220(::Programmer::Base &base) : P18F(base) {}
+ virtual void program(Type type);
+};
+
+//-----------------------------------------------------------------------------
+class P18F242 : public P18F
+{
+public:
+ P18F242(::Programmer::Base &base) : P18F(base) {}
+ virtual void configureSinglePanel();
+};
+
+//-----------------------------------------------------------------------------
+class P18F2539 : public P18F242
+{
+public:
+ P18F2539(::Programmer::Base &base) : P18F242(base) {}
+ virtual bool doErase(bool isProtected);
+ virtual bool doEraseCommand(uint cmd1, uint cmd2);
+};
+
+//-----------------------------------------------------------------------------
+class P18F2439 : public P18F2539
+{
+public:
+ P18F2439(::Programmer::Base &base) : P18F2539(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+};
+
+//-----------------------------------------------------------------------------
+class P18F2221 : public P18F
+{
+public:
+ P18F2221(::Programmer::Base &base) : P18F(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool isProtected);
+ virtual uint programLowTime() { return 100; }
+ virtual void unlockEeprom() {}
+};
+
+//-----------------------------------------------------------------------------
+class P18F6527 : public P18F2221
+{
+public:
+ P18F6527(::Programmer::Base &base) : P18F2221(base) {}
+ virtual bool doErase(bool isProtected);
+};
+
+//-----------------------------------------------------------------------------
+class P18F6310 : public P18F
+{
+public:
+ P18F6310(::Programmer::Base &base) : P18F(base) {}
+ virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; }
+ virtual uint programHighTime(Type type) const { return (type==Code ? 2000 : 30000); }
+ virtual uint programLowTime() { return 120; }
+ virtual bool doEraseRange(Pic::MemoryRangeType) { return false; }
+ virtual bool doErase(bool isProtected);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_30.cpp b/src/progs/direct/base/direct_30.cpp
new file mode 100644
index 0000000..db3c7f4
--- /dev/null
+++ b/src/progs/direct/base/direct_30.cpp
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * 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 "direct_30.h"
+
+const uint BULK_ERASE_SEQUENCE[] = { // for all dsPICs
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ Direct::Pic30::LoopStart + 2,
+ 0x24008A, 0x883B0A, // step 2
+ 0x200F80, 0x880190, 0x200067, // step 3
+ 0xBB0300, // step 4
+ 0xBB1B86, // step 5
+ 0x200558, 0x200AA9, 0x883B38, 0x883B39, // step 6
+ 0xA8E761, 0x000000, 0x000000, // step 7
+ Direct::Pic30::Pause + 2000000,
+ 0xA9E761, 0x000000, 0x000000,
+ Direct::Pic30::LoopEnd,
+ 0x2407FA, 0x883B0A, // step 9
+ 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 10
+ 0xA8E761, 0x000000, 0x000000, // step 11
+ Direct::Pic30::Pause + 2000000,
+ 0xA9E761, 0x000000, 0x000000,
+ Direct::Pic30::End
+};
+const uint READ_APPLICATION_ID_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ 0x200800, 0x880190, 0x205FE0, 0x207841, // step 2
+ 0xBA0890, 0x000000, 0x000000,
+ Direct::Pic30::RegisterOut, 0x000000, // step 3
+ Direct::Pic30::End
+};
+const uint READ_CONFIG_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ 0x200F80, 0x880190, 0xEB0300, 0xEB0380, // step 2
+ Direct::Pic30::LoopStart + 7,
+ 0xBA0BB6, 0x000000, 0x000000, 0x883C20, 0x000000, // step 3
+ Direct::Pic30::RegisterOut, 0x000000, // step 4
+ 0x040100, 0x000000, // step 5
+ Direct::Pic30::LoopEnd,
+ Direct::Pic30::End
+};
+const uint WRITE_CONFIG_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ Direct::Pic30::FillAddressLow + 0x200007, // step 2
+ 0x24008A, 0x883B0A, // step 3
+ 0x200F80, 0x880190, // step 4
+ Direct::Pic30::FillData + 0x200000, // step 5
+ //0xEB0300, ???
+ 0xBB1B96, 0x000000, 0x000000, // step 8
+ 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7
+ 0xA8E761, 0x000000, 0x000000, // step 8
+ Direct::Pic30::Pause + 2000000,
+ 0xA9E761, 0x000000, 0x000000,
+ Direct::Pic30::End
+};
+const uint READ_DATA_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200006, // step 2
+ 0xEB0380, // step 3
+ 0xBA1BB6, 0x000000, 0x000000,
+ 0xBA1BB6, 0x000000, 0x000000,
+ 0xBA1BB6, 0x000000, 0x000000,
+ 0xBA1BB6, 0x000000, 0x000000,
+ 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4
+ 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ Direct::Pic30::End
+};
+const uint WRITE_DATA_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ 0x24005A, 0x883B0A, // step 2
+ 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200007, // step 3
+ Direct::Pic30::LoopStart + 4,
+ Direct::Pic30::FillData + 0x200000, // step 4
+ Direct::Pic30::FillData + 0x200001,
+ Direct::Pic30::FillData + 0x200002,
+ Direct::Pic30::FillData + 0x200003,
+ 0xEB0300, 0x000000, // step 5
+ 0xBB1BB6, 0x000000, 0x000000,
+ 0xBB1BB6, 0x000000, 0x000000,
+ 0xBB1BB6, 0x000000, 0x000000,
+ 0xBB1BB6, 0x000000, 0x000000,
+ Direct::Pic30::LoopEnd,
+ 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7
+ 0xA8E761, 0x000000, 0x000000, // step 8
+ Direct::Pic30::Pause + 2000000,
+ 0xA9E761, 0x000000, 0x000000,
+ Direct::Pic30::End
+};
+const uint READ_CODE_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ Direct::Pic30::FillAddressHigh + 0x200000, // step 2
+ 0x880190, Direct::Pic30::FillAddressLow + 0x200006,
+ 0xEB0380, // step 3
+ 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000,
+ 0xBADBD6, 0x000000, 0x000000, 0xBA1BB6, 0x000000, 0x000000,
+ 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000,
+ 0xBADBD6, 0x000000, 0x000000, 0xBA0BB6, 0x000000, 0x000000,
+ 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4
+ 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C24, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ 0x883C25, 0x000000, Direct::Pic30::RegisterOut, 0x000000,
+ Direct::Pic30::End
+};
+const uint WRITE_CODE_SEQUENCE[] = {
+ 0x000000, 0x000000, 0x040100, 0x000000, // step 1
+ 0x24001A, 0x883B0A, // step 2
+ Direct::Pic30::FillAddressHigh + 0x200000, // step 3
+ 0x880190, Direct::Pic30::FillAddressLow + 0x200007,
+ Direct::Pic30::LoopStart + 8,
+ Direct::Pic30::FillData + 0x200000, // step 4
+ Direct::Pic30::FillData + 0x200001,
+ Direct::Pic30::FillData + 0x200002,
+ Direct::Pic30::FillData + 0x200003,
+ Direct::Pic30::FillData + 0x200004,
+ Direct::Pic30::FillData + 0x200005,
+ 0xEB0300, 0x000000, // step 5
+ 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000,
+ 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000,
+ 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000,
+ 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000,
+ Direct::Pic30::LoopEnd,
+ 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7
+ 0xA8E761, 0x000000, 0x000000, 0x000000, 0x000000, // step 8
+ Direct::Pic30::Pause + 2000000,
+ 0xA9E761, 0x000000, 0x000000, 0x000000, 0x000000,
+ Direct::Pic30::End
+};
+
+bool Direct::Pic30::sendCommand(Command cmd)
+{
+ for (uint i=0; i<4; i++) {
+ hardware().setPin(DataOut, ((cmd>>i) & 1 ? High : Low));
+ hardware().setPin(Clock, High);
+ Port::nsleep(100);
+ hardware().setPin(Clock, Low);
+ Port::nsleep(100);
+ }
+ return true;
+}
+
+bool Direct::Pic30::executeSIX(uint opcode)
+{
+ if ( !sendCommand(SIX) ) return false;
+ for (uint i=0; i<24; i++) {
+ hardware().setPin(DataOut, ((opcode>>i) & 1 ? High : Low));
+ hardware().setPin(Clock, High);
+ Port::nsleep(100);
+ hardware().setPin(Clock, Low);
+ // seem to need this longer delay here -- maybe
+ // specific to my programmer hardware? #### from dspicprg
+ Port::nsleep(5000);
+ }
+ return true;
+}
+
+bool Direct::Pic30::executeREGOUT(uint &v)
+{
+ v = 0;
+ if ( !sendCommand(REGOUT) ) return false;
+ hardware().setPin(DataOut, High);
+ for (uint i=0; i<24; i++) {
+ hardware().setPin(Clock, High);
+ Port::nsleep(100);
+ hardware().setPin(Clock, Low);
+ // as above, need extra delay here, but even
+ // longer in this case -- maybe data line takes
+ // longer to settle when it is being driven by
+ // the PIC than by the programmer? #### from dspicprg
+ Port::nsleep(10000);
+ if ( i>=8 ) {
+ uint r = hardware().readBit();
+ v |= (r << (i-8));
+ }
+ }
+ return true;
+}
+
+bool Direct::Pic30::doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData)
+{
+ uint loopStart = 0, loopCound = 0;
+ for (uint i=0; sequence[i]!=End; i++) {
+ uint opcode = (sequence[i] & OpcodeMask);
+ switch (Operation(sequence[i] & OperationMask)) {
+ case SendSix:
+ if ( !executeSIX(opcode) ) return false;
+ break;
+ case RegisterOut: {
+ uint v;
+ if ( !executeREGOUT(v) ) return false;
+ (*inData) = v & 0xFF;
+ inData++;
+ (*inData) = (v >> 8) & 0xFF;
+ inData++;
+ break;
+ }
+ case Pause:
+ Port::nsleep(opcode);
+ break;
+ case LoopStart:
+ loopCound = opcode;
+ loopStart = i;
+ break;
+ case LoopEnd:
+ loopCound--;
+ if (loopCound) i = loopStart;
+ break;
+ case FillData: {
+ uint v = *outData;
+ v <<= 4;
+ outData++;
+ v |= *outData;
+ outData++;
+ v <<= 4;
+ executeSIX(v | opcode);
+ break;
+ }
+ case FillAddressLow: {
+ uint v = address & 0xFFFF;
+ v <<= 4;
+ executeSIX(v | opcode);
+ break;
+ }
+ case FillAddressHigh: {
+ uint v = (address & 0xFF0000) >> 16;
+ v <<= 4;
+ executeSIX(v | opcode);
+ break;
+ }
+ case End: Q_ASSERT(false); break;
+ }
+ }
+ return true;
+}
+
+bool Direct::Pic30::doErase(bool)
+{
+ if ( !enterStdpMode() ) return false;
+ if ( !doStdpSequence(BULK_ERASE_SEQUENCE, 0, 0, 0) ) return false;
+ return exitStdpMode();
+}
+
+bool Direct::Pic30::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data)
+{
+ // #### TODO
+ return false;
+}
+
+bool Direct::Pic30::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
+{
+ // #### TODO
+ return false;
+}
diff --git a/src/progs/direct/base/direct_30.h b/src/progs/direct/base/direct_30.h
new file mode 100644
index 0000000..458496e
--- /dev/null
+++ b/src/progs/direct/base/direct_30.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * 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 DIRECT_30_H
+#define DIRECT_30_H
+
+#include "direct_pic.h"
+
+namespace Direct
+{
+//----------------------------------------------------------------------------
+class Pic30 : public PicDeviceSpecific
+{
+public:
+ Pic30(::Programmer::Base &base) : PicDeviceSpecific(base) {}
+ virtual bool doErase(bool isProtected);
+ virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data);
+ virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force);
+ virtual bool setPowerOn() { return setPowerOnVddFirst(); }
+
+public:
+ enum Operation { SendSix = 0x0000000, RegisterOut = 0x1000000, Pause = 0x2000000,
+ LoopStart = 0x3000000, LoopEnd = 0x4000000, FillData = 0x5000000,
+ FillAddressLow = 0x6000000, FillAddressHigh = 0x7000000, End = 0x8000000 };
+ enum Mask { OperationMask = 0xF000000, OpcodeMask = 0x0FFFFFF };
+
+private:
+ bool enterStdpMode() { return pulseEngine("cdB"); }
+ bool exitStdpMode() { return pulseEngine("cdb"); }
+ bool doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData);
+ enum Command { SIX = 0x0, REGOUT = 0x1 };
+ bool sendCommand(Command command);
+ bool executeSIX(uint opcode);
+ bool executeREGOUT(uint &value);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_baseline.cpp b/src/progs/direct/base/direct_baseline.cpp
new file mode 100644
index 0000000..996eb12
--- /dev/null
+++ b/src/progs/direct/base/direct_baseline.cpp
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * 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 "direct_baseline.h"
+
+//----------------------------------------------------------------------------
+bool Direct::Baseline::gotoMemory(Pic::MemoryRangeType type)
+{
+ switch (type.type()) {
+ case Pic::MemoryRangeType::Config: return true;
+ case Pic::MemoryRangeType::Eeprom: return true;
+ case Pic::MemoryRangeType::Code:
+ case Pic::MemoryRangeType::Cal:
+ case Pic::MemoryRangeType::UserId:
+ case Pic::MemoryRangeType::CalBackup: return incrementPC(device().range(type).start.toUInt()+1);
+ 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 Direct::P12C5XX::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i)
+{
+ BitValue word = data[i];
+ // config requires a total of 10ms Pulses == 100 x 100 us
+ uint total = (type==Pic::MemoryRangeType::Config ? 100 : 8);
+ uint n = 0;
+ for (; n<total; n++) {
+ pulseEngine("k2,S,k8,w100,k14,w5000", word);
+ if ( readWord(type)==word ) break;
+ }
+ if ( n==total ) return false;
+ if ( type!=Pic::MemoryRangeType::Config ) {
+ // 11 x (n+1) additionnal passes
+ for (uint k = 0; k<11*(n+1); k++)
+ pulseEngine("k2,S,k8,w100,k14,w5000", word);
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P10F2XX::doEraseRange(Pic::MemoryRangeType type)
+{
+ Q_ASSERT( type==Pic::MemoryRangeType::Code );
+ Device::Array array;
+ if ( !doRead(Pic::MemoryRangeType::Config, array, 0) ) return false;
+ gotoMemory(Pic::MemoryRangeType::Config);
+ pulseEngine("k9,w10000"); // 10ms
+ return doWrite(Pic::MemoryRangeType::Config, array, true);
+}
+
+bool Direct::P10F2XX::doErase(bool)
+{
+ gotoMemory(Pic::MemoryRangeType::UserId);
+ pulseEngine("k9,w10000"); // 10ms
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+bool Direct::P12C67X::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i)
+{
+ BitValue word = data[i];
+ // config requires a total of 10ms Pulses == 100 x 100 us
+ uint total = (type==Pic::MemoryRangeType::Config ? 100 : 25);
+ uint n = 0;
+ for (; n<total; n++) {
+ pulseEngine("k2,S,k8,w100,k14,w5000", word);
+ if ( readWord(type)==word ) break;
+ }
+ if ( n==total ) return false;
+ if ( type!=Pic::MemoryRangeType::Config ) {
+ // 3 x (n+1) additionnal passes
+ for (uint k = 0; k<3*(n+1); k++)
+ pulseEngine("k2,S,k8,w100,k14,w5000", word);
+ }
+ return true;
+}
diff --git a/src/progs/direct/base/direct_baseline.h b/src/progs/direct/base/direct_baseline.h
new file mode 100644
index 0000000..0987dea
--- /dev/null
+++ b/src/progs/direct/base/direct_baseline.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * 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 DIRECT_BASELINE_HH
+#define DIRECT_BASELINE_HH
+
+#include "direct_16F.h"
+
+namespace Direct
+{
+//-----------------------------------------------------------------------------
+class Baseline : public pic16
+{
+public:
+ Baseline(::Programmer::Base &base) : pic16(base) {}
+ virtual bool gotoMemory(Pic::MemoryRangeType type);
+ virtual bool setPowerOn() { return setPowerOnVppFirst(); }
+};
+
+//-----------------------------------------------------------------------------
+class P12C5XX : public Baseline
+{
+public:
+ P12C5XX(::Programmer::Base &base) : Baseline(base) {}
+ virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i);
+ virtual bool doEraseRange(Pic::MemoryRangeType) { return false; }
+ virtual bool doErase(bool) { return false; }
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused
+};
+
+//-----------------------------------------------------------------------------
+class P10F2XX : public Baseline
+{
+public:
+ P10F2XX(::Programmer::Base &base) : Baseline(base) {}
+ virtual bool doEraseRange(Pic::MemoryRangeType type);
+ virtual bool doErase(bool);
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; }
+ virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,w100"); }
+};
+
+class P16F57 : public P10F2XX
+{
+public:
+ P16F57(::Programmer::Base &base) : P10F2XX(base) {}
+ virtual uint nbWordsCodeProg() const { return 4; }
+};
+
+//-----------------------------------------------------------------------------
+class P12C67X : public P16F
+{
+public:
+ P12C67X(::Programmer::Base &base) : P16F(base) {}
+ virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i);
+ virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused
+ virtual bool doEraseRange(Pic::MemoryRangeType) { return false; }
+ virtual bool doErase(bool) { return false; }
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_data.h b/src/progs/direct/base/direct_data.h
new file mode 100644
index 0000000..0b84084
--- /dev/null
+++ b/src/progs/direct/base/direct_data.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_DATA_H
+#define DIRECT_DATA_H
+
+namespace Direct
+{
+
+struct Data {
+};
+extern const Data &data(const QString &device);
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_mem24.cpp b/src/progs/direct/base/direct_mem24.cpp
new file mode 100644
index 0000000..a719add
--- /dev/null
+++ b/src/progs/direct/base/direct_mem24.cpp
@@ -0,0 +1,207 @@
+/***************************************************************************
+ * 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 "direct_mem24.h"
+
+#include <qdatetime.h>
+
+#include "common/global/global.h"
+#include "common/common/misc.h"
+
+Direct::Mem24DeviceSpecific::Mem24DeviceSpecific(::Programmer::Base &base)
+ : ::Programmer::Mem24DeviceSpecific(base)
+{}
+
+bool Direct::Mem24DeviceSpecific::setPowerOn()
+{
+ hardware().setPin(Clock, Low);
+ hardware().setPin(DataOut, Low);
+ hardware().setPin(Vpp, Off);
+ if ( hardware().isGroundPin(Vdd) ) {
+ hardware().setPin(Clock, High);
+ Port::usleep(500000);
+ } else {
+ hardware().setPin(Vdd, On);
+ Port::usleep(10000);
+ }
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::setPowerOff()
+{
+ hardware().setPin(Clock, Low);
+ hardware().setPin(DataOut, Low);
+ hardware().setPin(Vpp, Off);
+ hardware().setPin(Vdd, Off);
+ Port::usleep(10000);
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::verifyPresence()
+{
+ if ( !start() ) return false;
+ bool acked;
+ if ( !writeByte(controlByte(0x0, Write), acked) ) return false;
+ if ( !acked ) {
+ log(Log::LineType::Error, i18n("Could not detect EEPROM"));
+ return false;
+ }
+ log(Log::LineType::Information, i18n("EEPROM detected"));
+ return stop();
+}
+
+uint Direct::Mem24DeviceSpecific::controlByte(uint address, Operation operation) const
+{
+ uint cbyte = (operation==Write ? 0xA0 : 0xA1);
+ uint bsize = device().nbBytes() / device().nbBlocks();
+ uint block = address / bsize;
+ uint nbb = nbBits(device().nbBlocks()-1);
+ for (uint i=0; i<nbb; i++)
+ if ( block & (1<<i) ) cbyte |= 1 << (4-nbb+i);
+ return cbyte;
+}
+
+bool Direct::Mem24DeviceSpecific::setAddress(uint address)
+{
+ log(Log::DebugLevel::Extra, QString("set address %1").arg(toHexLabel(address, nbChars(NumberBase::Hex, address))));
+ if ( !start() ) return false;
+ uint bsize = device().nbBytes() / device().nbBlocks();
+ uint block = address / bsize;
+ log(Log::DebugLevel::Extra, QString(" in block #%1/%2").arg(block).arg(device().nbBlocks()));
+ uint cbyte = controlByte(address, Write);
+ log(Log::DebugLevel::Max, QString(" control byte is %1").arg(toHexLabel(cbyte, 2)));
+ if ( !writeByteAck(cbyte) ) return false;
+ uint nb = nbBytes(bsize-1);
+ for (int i=nb-1; i>=0; i--) {
+ uint add = (address >> 8*i) & 0xFF;
+ log(Log::DebugLevel::Max, QString(" byte #%1: %2").arg(i).arg(toHexLabel(add, 2)));
+ if ( !writeByteAck(add) ) return false;
+ }
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::doRead(Device::Array &data, const ::Programmer::VerifyData *vdata)
+{
+ // sequential read: all device memory
+ if ( !setAddress(0x0) ) return false;
+ if ( !start() ) return false;
+ if ( !writeByteAck(controlByte(0x0, Read)) ) return false;
+ data.resize(device().nbBytes());
+ for (uint i=0; i<data.count()-1; i++) data[i] = readByte(Low);
+ data[data.count()-1] = readByte(High);
+ if (vdata) {
+ for (uint i=0; i<data.count(); i++)
+ if ( !verifyByte(i, data[i], *vdata) ) return false;
+ }
+ return stop();
+}
+
+bool Direct::Mem24DeviceSpecific::doWrite(const Device::Array &data)
+{
+ QTime time;
+ // page by page (page_size==1: byte by byte)
+ uint nbPages = device().nbBytes() / device().nbBytesPage();
+ for (uint i=0; i<nbPages; i++) {
+ log(Log::DebugLevel::Extra, QString("write page #%1/%2").arg(i).arg(nbPages));
+ uint address = i * device().nbBytesPage();
+ // write bytes
+ if ( !setAddress(address) ) return false;
+ for (uint k=0; k<device().nbBytesPage(); k++)
+ if ( !writeByteAck(data[address+k]) ) return false;
+ if ( !stop() ) return false;
+ // poll
+ time.start();
+ for (;;) {
+ if ( !start() ) return false;
+ bool acked;
+ if ( !writeByte(controlByte(address, Write), acked) ) return false;
+ if (acked) break;
+ if ( time.elapsed()>200 ) { // 200 ms timeout
+ log(Log::LineType::Error, i18n("Timeout writing at address %1").arg(toHexLabel(address, nbChars(device().nbBytes()))));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void Direct::Mem24DeviceSpecific::set(State clock, State data)
+{
+ hardware().setPin(Clock, clock);
+ hardware().setPin(DataOut, data);
+ Port::usleep(5); // #### needed ?
+}
+
+void Direct::Mem24DeviceSpecific::setData(State data)
+{
+ set(Low, data);
+ set(High, data);
+ set(Low, data);
+}
+
+BitValue Direct::Mem24DeviceSpecific::readByte(State ack)
+{
+ hardware().setRead();
+ set(Low, High);
+ BitValue b = 0;
+ for (uint i=0; i<8; i++) {
+ set(High, High);
+ b <<= 1;
+ if ( hardware().readBit() ) b |= 0x1;
+ set(Low, High);
+ }
+ hardware().setWrite();
+ setData(ack);
+ return b;
+}
+
+bool Direct::Mem24DeviceSpecific::writeByteAck(BitValue value)
+{
+ bool acked;
+ if ( !writeByte(value, acked) ) return false;
+ if (!acked) {
+ log(Log::LineType::Error, i18n("Acknowledge bit incorrect"));
+ return false;
+ }
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::writeByte(BitValue value, bool &acked)
+{
+ Q_ASSERT( value<=0xFF );
+ hardware().setWrite();
+ set(Low, Low);
+ for (int i=7; i>=0; i--) setData(value.bit(i) ? High : Low);
+ hardware().setRead();
+ set(Low, High);
+ set(High, High);
+ acked = !hardware().readBit();
+ hardware().setWrite();
+ set(Low, High);
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::start()
+{
+ hardware().setWrite();
+ set(Low, High);
+ set(High, High);
+ set(High, Low);
+ set(Low, Low);
+ return true;
+}
+
+bool Direct::Mem24DeviceSpecific::stop()
+{
+ hardware().setWrite();
+ set(Low, Low);
+ set(High, Low);
+ set(High, High);
+ set(Low, High);
+ return true;
+}
diff --git a/src/progs/direct/base/direct_mem24.h b/src/progs/direct/base/direct_mem24.h
new file mode 100644
index 0000000..64f2a9d
--- /dev/null
+++ b/src/progs/direct/base/direct_mem24.h
@@ -0,0 +1,47 @@
+/***************************************************************************\
+ * 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 DIRECT_MEM24_H
+#define DIRECT_MEM24_H
+
+#include "devices/mem24/prog/mem24_prog.h"
+#include "direct.h"
+
+namespace Direct
+{
+
+class Mem24DeviceSpecific : public ::Programmer::Mem24DeviceSpecific
+{
+public:
+ Mem24DeviceSpecific(::Programmer::Base &base);
+ virtual Hardware &hardware() { return static_cast<Hardware &>(*_base.hardware()); }
+ const Mem24::Data &device() const { return static_cast<const Mem24::Data &>(*::Programmer::DeviceSpecific::_base.device()); }
+ virtual bool init() { return true; }
+ virtual bool setPowerOff();
+ virtual bool setPowerOn();
+ virtual bool setTargetPowerOn(bool) { return true; }
+ virtual bool verifyPresence();
+
+private:
+ virtual bool doRead(Device::Array &data, const ::Programmer::VerifyData *vdata);
+ virtual bool doWrite(const Device::Array &data);
+ bool start();
+ bool stop();
+ BitValue readByte(State ack);
+ bool writeByte(BitValue value, bool &acked);
+ bool writeByteAck(BitValue value);
+ void set(State clock, State data);
+ void setData(State data);
+ enum Operation { Write, Read };
+ uint controlByte(uint address, Operation operation) const;
+ bool setAddress(uint address);
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_pic.cpp b/src/progs/direct/base/direct_pic.cpp
new file mode 100644
index 0000000..30e4722
--- /dev/null
+++ b/src/progs/direct/base/direct_pic.cpp
@@ -0,0 +1,187 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_pic.h"
+
+#include "common/common/misc.h"
+
+//-----------------------------------------------------------------------------
+Direct::PulseEngine::PulseEngine(::Programmer::Base &base)
+ : _pbase(base)
+{
+ _clockDelay = 0;
+}
+
+BitValue Direct::PulseEngine::pulseEngine(const QString &cmd, BitValue value)
+{
+ _pbase.log(Log::DebugLevel::Extra, QString("pulse engine: %1").arg(cmd));
+ QByteArray a = toAscii(cmd);
+ BitValue res = 0;
+ for (const char *ptr=a.data(); (ptr-a.data())<int(a.count()); ++ptr)
+ if ( !pulse(ptr, value, res) ) qFatal("pulse engine: invalid command '%c'", *ptr);
+ return res;
+}
+
+// Electric signals level commands:
+// UPPER case means signal High - lower case means Low
+// Example: "cPCcp" means "clock-low, power on, clock high, clock low, power off".
+// c/C = clock
+// d/D = data
+// p/P = power (vdd)
+// Higher level commands:
+// wnnnnn = wait nnnnn microseconds (nnnnn is decimal)
+// , = a shorthand for w1
+// ; or space = NOP (can be used as separator - useful in debug mode)
+bool Direct::PulseEngine::pulse(const char * &cmd, BitValue, BitValue &)
+{
+ switch (*cmd) {
+ case ';':
+ case ' ':
+ _pbase.log(Log::DebugLevel::Max, "NOP");
+ break;
+ case 'c':
+ _pbase.log(Log::DebugLevel::Max, "CLOCK L");
+ hardware().setPin(Clock, Low);
+ break;
+ case 'C':
+ _pbase.log(Log::DebugLevel::Max, "CLOCK H");
+ hardware().setPin(Clock, High);
+ break;
+ case 'd':
+ _pbase.log(Log::DebugLevel::Max, "DATA L");
+ hardware().setPin(DataOut, Low);
+ break;
+ case 'D':
+ _pbase.log(Log::DebugLevel::Max, "DATA H");
+ hardware().setPin(DataOut, High);
+ break;
+ case 'p':
+ _pbase.log(Log::DebugLevel::Max, "VDD Off");
+ hardware().setPin(Vdd, Off);
+ Port::usleep(10000);
+ break;
+ case 'P':
+ _pbase.log(Log::DebugLevel::Max, "VDD On");
+ hardware().setPin(Vdd, On);
+ // wait 10ms for ALL devices because some programmers (or target board) have capacitors to charge
+ Port::usleep(10000);
+ break;
+ case 'w': {
+ uint n = 0;
+ for(; *(cmd+1) && isdigit((int)*(cmd+1)); ++cmd)
+ n = (n * 10) + *(cmd+1) - '0';
+ _pbase.log(Log::DebugLevel::Max, "WAIT " + QString::number(n) + " micro-sec.");
+ Port::usleep(n);
+ break;
+ }
+ case ',':
+ _pbase.log(Log::DebugLevel::Max, "WAIT 1 micro-sec");
+ Port::usleep(1);
+ break;
+ default: return false;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+Direct::PicDeviceSpecific::PicDeviceSpecific(::Programmer::Base &base)
+ : ::Programmer::PicDeviceSpecific(base), PulseEngine(base)
+{}
+
+// Electric signals level commands:
+// UPPER case means signal High - lower case means Low
+// b/B = burn (vpp)
+bool Direct::PicDeviceSpecific::pulse(const char *&cmd, BitValue value, BitValue &res)
+{
+ switch (*cmd) {
+ case 'b':
+ log(Log::DebugLevel::Max, "VPP Off");
+ hardware().setPin(Vpp, Off);
+ Port::usleep(10); // 10us
+ break;
+ case 'B':
+ log(Log::DebugLevel::Max, "VPP On");
+ hardware().setPin(Vpp, On);
+ Port::usleep(100000); // 100ms
+ break;
+ default: return PulseEngine::pulse(cmd, value, res);
+ }
+ return true;
+}
+
+bool Direct::PicDeviceSpecific::setPowerOnVddFirst()
+{
+ setPowerOff();
+ switch (hardware().type()) {
+ case Normal:
+ if ( hardware().isGroundPin(Vdd) ) { // some programmer cannot change Vdd independently
+ pulseEngine("B"); // charge capacitor to have high Vdd
+ pulseEngine("bB"); // turn off Vpp briefly, Vpp on
+ } else pulseEngine("PB");
+ break;
+ case EPEToolkitMK3:
+ pulseEngine("B"); // put MCLR at 0V
+ pulseEngine("bP"); // put MCLR on multiplexer and turn multiplexer to 12V
+ break;
+ }
+ return true;
+}
+
+bool Direct::PicDeviceSpecific::setPowerOnVppFirst()
+{
+ setPowerOff();
+ pulseEngine("BP");
+ return true;
+}
+
+bool Direct::PicDeviceSpecific::setPowerOff()
+{
+ pulseEngine("cdpb"); // turn off Vpp after Vdd to prevent running device
+ pulseEngine("w50000"); // to be on the safe size with multiple on/off
+ return true;
+}
+
+bool Direct::PicDeviceSpecific::setTargetPowerOn(bool on)
+{
+ pulseEngine(on ? "P" : "p");
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Higher level commands:
+// S = send data word
+// R = read data word
+// r = read byte
+// knn = send 6 or 4 bits command nn to PIC (nn is decimal)
+bool Direct::Pic8DeviceSpecific::pulse(const char *&cmd, BitValue value, BitValue &res)
+{
+ switch (*cmd) {
+ case 'S':
+ log(Log::DebugLevel::Max, "SEND " + toHexLabel(value, 4));
+ send_word(value);
+ break;
+ case 'R':
+ log(Log::DebugLevel::Max, "Read Word");
+ res = get_word();
+ break;
+ case 'r':
+ log(Log::DebugLevel::Max, "Read Byte");
+ res = get_byte();
+ break;
+ case 'k': {
+ uint n = 0;
+ for(; *(cmd+1) && isdigit((int)*(cmd+1)); ++cmd)
+ n = (n * 10) + *(cmd+1) - '0';
+ log(Log::DebugLevel::Max, "SEND cmd " + QString::number(n));
+ send_cmd(n);
+ break;
+ }
+ default: return PicDeviceSpecific::pulse(cmd, value, res);
+ }
+ return true;
+}
diff --git a/src/progs/direct/base/direct_pic.h b/src/progs/direct/base/direct_pic.h
new file mode 100644
index 0000000..39cd97c
--- /dev/null
+++ b/src/progs/direct/base/direct_pic.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_PIC_H
+#define DIRECT_PIC_H
+
+#include "devices/pic/pic/pic_memory.h"
+#include "direct.h"
+
+namespace Direct
+{
+//-----------------------------------------------------------------------------
+class PulseEngine
+{
+public:
+ PulseEngine(::Programmer::Base &base);
+ virtual ~PulseEngine() {}
+ BitValue pulseEngine(const QString &command, BitValue value = 0);
+
+protected:
+ ::Programmer::Base &_pbase;
+ uint _clockDelay; // additionnal delay for buggy hardware
+
+ virtual bool pulse(const char *&cmd, BitValue value, BitValue &res);
+ virtual Hardware &hardware() { return static_cast<Hardware &>(*_pbase.hardware()); }
+};
+
+//-----------------------------------------------------------------------------
+class PicDeviceSpecific : public ::Programmer::PicDeviceSpecific, public PulseEngine
+{
+public:
+ PicDeviceSpecific(::Programmer::Base &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; }
+ virtual bool setPowerOff();
+ virtual bool setTargetPowerOn(bool on);
+
+protected:
+ virtual bool pulse(const char *&cmd, BitValue value, BitValue &res);
+ bool setPowerOnVddFirst();
+ bool setPowerOnVppFirst();
+};
+
+//-----------------------------------------------------------------------------
+class Pic8DeviceSpecific : public PicDeviceSpecific
+{
+public:
+ Pic8DeviceSpecific(::Programmer::Base &base) : PicDeviceSpecific(base) {}
+
+protected:
+ virtual bool pulse(const char *&cmd, BitValue value, BitValue &res);
+ virtual void send_word(BitValue word) = 0;
+ virtual void send_bits(BitValue d, uint nbBits) = 0;
+ virtual void send_cmd(BitValue d) = 0;
+ virtual BitValue get_word() = 0;
+ virtual BitValue get_byte() = 0;
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/base/direct_prog.cpp b/src/progs/direct/base/direct_prog.cpp
new file mode 100644
index 0000000..3e4f168
--- /dev/null
+++ b/src/progs/direct/base/direct_prog.cpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_prog.h"
+
+#include "devices/base/device_group.h"
+#include "devices/list/device_list.h"
+#include "direct_prog_config.h"
+#include "direct_mem24.h"
+//#include "direct_30.h"
+
+Hardware::Config *Direct::DGroup::hardwareConfig() const
+{
+ return new Config;
+}
+
+void Direct::DGroup::initSupported()
+{
+ Group::initSupported();
+ // const ::Group::Base *gpic = Device::lister().group("pic");
+ ::Group::Base::ConstIterator pit;
+ // for (pit=gpic->begin(); pit!=gpics->end(); ++pit) {
+ // ::Group::DeviceData data = pit.data();
+ // if ( static_cast<const Pic::Data *>(data.data)->architecture()!=Pic::Architecture::P30X ) continue;
+ // data.supportType = ::Group::Untested;
+ // addDevice(data);
+ // }
+ const ::Group::Base *gmem24 = Device::lister().group("mem24");
+ for (pit=gmem24->begin(); pit!=gmem24->end(); ++pit) addDevice(pit.key(), pit.data().data, pit.data().support);
+}
+
+::Programmer::Base *Direct::DGroup::createBase(const Device::Data *data) const
+{
+ if ( data==0 || data->group().name()=="pic" ) return new PicBase(*this, static_cast<const Pic::Data *>(data));
+ return new Mem24Base(*this, static_cast<const Mem24::Data *>(data));
+}
+
+::Programmer::Hardware *Direct::DGroup::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const
+{
+ Config config;
+ HardwareData *hdata = static_cast<HardwareData *>(config.hardwareData(hd.name));
+ Q_ASSERT( hdata->portType==hd.port.type );
+ ::Programmer::Hardware *hardware = 0;
+ if ( hd.port.type==PortType::Serial ) hardware = new SerialHardware(base, hd.port.device, *hdata);
+ else hardware = new ParallelHardware(base, hd.port.device, *hdata);
+ delete hdata;
+ return hardware;
+}
+
+::Programmer::DeviceSpecific *Direct::DGroup::createDeviceSpecific(::Programmer::Base &base) const
+{
+ if ( base.device()->group().name()=="pic" ) {
+ // if ( static_cast<const Pic::Data *>(base.device())->architecture()==Pic::Architecture::P30X ) return new Pic30(base);
+ return Group::createDeviceSpecific(base);
+ }
+ return new Mem24DeviceSpecific(base);
+}
diff --git a/src/progs/direct/base/direct_prog.h b/src/progs/direct/base/direct_prog.h
new file mode 100644
index 0000000..34ca0b7
--- /dev/null
+++ b/src/progs/direct/base/direct_prog.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_PROG_H
+#define DIRECT_PROG_H
+
+#include "common/global/global.h"
+#include "progs/base/prog_group.h"
+#include "devices/pic/prog/pic_prog.h"
+#include "devices/mem24/prog/mem24_prog.h"
+#include "direct.h"
+
+namespace Direct
+{
+ extern bool isSupported(const QString &device);
+ class Hardware;
+
+//----------------------------------------------------------------------------
+class PicBase : public ::Programmer::PicBase
+{
+Q_OBJECT
+public:
+ PicBase(const ::Programmer::Group &group, const Pic::Data *data)
+ : ::Programmer::PicBase(group, data, "pic_direct_programmer") {}
+
+private:
+ Hardware &hardware() { return static_cast<Hardware &>(*_hardware); }
+};
+
+//----------------------------------------------------------------------------
+class Mem24Base : public ::Programmer::Mem24Base
+{
+Q_OBJECT
+public:
+ Mem24Base(const ::Programmer::Group &group, const Mem24::Data *data)
+ : ::Programmer::Mem24Base(group, data, "mem24_direct_programmer") {}
+
+private:
+ Hardware &hardware() { return static_cast<Hardware &>(*_hardware); }
+};
+
+//----------------------------------------------------------------------------
+class Group : public ::Programmer::PicGroup // methods defined in direct_data.cpp
+{
+protected:
+ virtual void initSupported();
+ virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const;
+};
+
+class DGroup : public Group
+{
+public:
+ virtual QString name() const { return "direct"; }
+ virtual QString label() const { return i18n("Direct Programmer"); }
+ virtual ::Hardware::Config *hardwareConfig() const;
+ virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; }
+ virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; }
+ virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::Parallel ); }
+
+protected:
+ virtual void initSupported();
+ virtual ::Programmer::Base *createBase(const Device::Data *data) const;
+ 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/direct/base/direct_prog_config.cpp b/src/progs/direct/base/direct_prog_config.cpp
new file mode 100644
index 0000000..ffce899
--- /dev/null
+++ b/src/progs/direct/base/direct_prog_config.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_prog_config.h"
+
+//-----------------------------------------------------------------------------
+struct ConstHardwareData
+{
+ PortType portType;
+ Direct::HData data;
+};
+
+struct ConstStandardHardwareData
+{
+ ::Hardware::DataInfo info;
+ ConstHardwareData data;
+};
+
+const ConstStandardHardwareData STANDARD_HARDWARE_DATA[] = {
+ { { "Tait classic", I18N_NOOP("Tait classic"), 0 },
+ { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "Tait 7405/7406", I18N_NOOP("Tait 7405/7406"), 0 },
+ { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } },
+ { { "P16PRO40 classic", I18N_NOOP("P16PRO40 classic"), 0 },
+ { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } },
+ { { "P16PRO40 7407", I18N_NOOP("P16PRO40 7407"), 0 },
+ { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "P16PRO40-VPP40 classic", I18N_NOOP("P16PRO40-VPP40 classic"), 0 },
+ { PortType::Parallel, { { 6, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } },
+ { { "P16PRO40-VPP40 7407", I18N_NOOP("P16PRO40-VPP40 7407"), 0 },
+ { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "EPIC+", I18N_NOOP("EPIC+"),
+ I18N_NOOP("You must disconnect 7407 pin 2") },
+ { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "JDM classic", I18N_NOOP("JDM classic"), 0 },
+ { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 0, Direct::Normal } } },
+ { { "JDM classic (delay 10)", I18N_NOOP("JDM classic (delay 10)"), 0 },
+ { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 10, Direct::Normal } } },
+ { { "JDM classic (delay 20)", I18N_NOOP("JDM classic (delay 20)"), 0 },
+ { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 20, Direct::Normal } } },
+ { { "PIC Elmer", I18N_NOOP("PIC Elmer"), 0 },
+ { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } },
+ { { "Velleman K8048", I18N_NOOP("Velleman K8048"), 0 },
+ { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } },
+ { { "HOODMICRO", I18N_NOOP("HOODMICRO"),
+ I18N_NOOP("Webpage: <a href=\"htpp://k9spud.com/hoodmicro\">htpp://k9spud.com/hoodmicro</a>") },
+ { PortType::Serial, { { 4, 5, 7, 3, 8, 5 }, 0, Direct::Normal } } },
+
+ //Added by Mirko Panciri 10/03/2004...
+ //Visit http://www.pic-tools.com
+ //I have tested only the "Asix Piccolo" version...
+ //I think the lines is the same of "Asix Piccolo Grande"...
+ { { "Asix Piccolo", I18N_NOOP("Asix Piccolo"), 0 },
+ { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } },
+ { { "Asix Piccolo Grande", I18N_NOOP("Asix Piccolo Grande"), 0 },
+ { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } },
+
+ { { "Propic2 Vpp-1", I18N_NOOP("Propic2 Vpp-1"), 0 },
+ { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "Propic2 Vpp-2", I18N_NOOP("Propic2 Vpp-2"), 0 },
+ { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "Propic2 Vpp-3", I18N_NOOP("Propic2 Vpp-3"), 0 },
+ { PortType::Parallel, { { -7, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "Myke's EL Cheapo", I18N_NOOP("Myke's EL Cheapo"), 0 },
+ { PortType::Parallel, { { 16, 25, -1,-17, 13, 25 }, 0, Direct::Normal } } },
+ { { "EL Cheapo classic", I18N_NOOP("EL Cheapo classic"), I18N_NOOP("Not tested.") },
+ { PortType::Parallel, { { 16, 25, 1, 17,-13, 25 }, 0, Direct::Normal } } },
+ { { "Monty-Robot programmer", I18N_NOOP("Monty-Robot programmer"), 0 },
+ { PortType::Parallel, { { -5, 4, 2, 3, 10, 25 }, 0, Direct::Normal } } },
+ { { "EPE Toolkit mk3", I18N_NOOP("EPE Toolkit mk3"),
+ I18N_NOOP("This programmer pulses MCLR from 5V to 0V and then 12V to enter programming mode. It uses a multiplexer to switch between 5V and 12V (Vdd is here the multiplexer pin).<p>Webpage: <a href=\"http://www.epemag.wimborne.co.uk/1001.htm\">http://www.epemag.wimborne.co.uk/1001.htm</a>") },
+ { PortType::Parallel, { { 5, 6, 3, 2, 10, 25 }, 0, Direct::EPEToolkitMK3 } } },
+
+ { { "ETT High Vpp", I18N_NOOP("ETT High Vpp"), 0 },
+ { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } },
+ { { "ETT Low Vpp", I18N_NOOP("ETT Low Vpp"),
+ I18N_NOOP("Compatible with ET-CAB10PIN V2 programmer shipped by Futurlec, with their PIC16F877 controler board.") },
+ { PortType::Parallel, { { 3, 5, 2, -1, 10, 25 }, 0, Direct::Normal } } },
+
+ { { 0, 0, 0 },
+ { PortType::Serial, { { 0, 0, 0, 0, 0, 0 }, 0, Direct::Normal } } }
+};
+
+//-----------------------------------------------------------------------------
+void Direct::HardwareData::readConfig(GenericConfig &config)
+{
+ ::Hardware::Data::readConfig(config);
+ for (uint i=0; i<Nb_PinTypes; i++) data.pins[i] = config.readIntEntry(PIN_DATA[i].key);
+ data.clockDelay = config.readIntEntry("clkdelay");
+}
+
+void Direct::HardwareData::writeConfig(GenericConfig &config) const
+{
+ ::Hardware::Data::writeConfig(config);
+ for (uint i=0; i<Nb_PinTypes; i++) config.writeEntry(PIN_DATA[i].key, data.pins[i]);
+ config.writeEntry("clkdelay", data.clockDelay);
+}
+
+bool Direct::HardwareData::isEqual(const ::Hardware::Data &cdata) const
+{
+ if ( !::Hardware::Data::isEqual(cdata) ) return false;
+ const HData &hdata = static_cast<const HardwareData &>(cdata).data;
+ if ( data.clockDelay!=hdata.clockDelay ) return false;
+ for (uint i=0; i<Nb_PinTypes; i++)
+ if ( data.pins[i]!=hdata.pins[i] ) return false;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+QStringList Direct::Config::standardHardwareNames(PortType type) const
+{
+ QStringList names;
+ for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++)
+ if ( STANDARD_HARDWARE_DATA[i].data.portType==type ) names += STANDARD_HARDWARE_DATA[i].info.name;
+ return names;
+}
+
+const Hardware::DataInfo *Direct::Config::standardHardwareDataInfo(const QString &name) const
+{
+ for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++) {
+ const ConstStandardHardwareData &csdata = STANDARD_HARDWARE_DATA[i];
+ if ( csdata.info.name==name) return &csdata.info;
+ }
+ return 0;
+}
+
+Hardware::Data *Direct::Config::standardHardwareData(const QString &name) const
+{
+ for (uint i=0; STANDARD_HARDWARE_DATA[i].info.name; i++) {
+ const ConstStandardHardwareData &csdata = STANDARD_HARDWARE_DATA[i];
+ if ( csdata.info.name!=name) continue;
+ HardwareData *data = new HardwareData;
+ data->name = csdata.info.name;
+ data->portType = csdata.data.portType;
+ data->data = csdata.data.data;
+ return data;
+ }
+ return 0;
+}
diff --git a/src/progs/direct/base/direct_prog_config.h b/src/progs/direct/base/direct_prog_config.h
new file mode 100644
index 0000000..151b141
--- /dev/null
+++ b/src/progs/direct/base/direct_prog_config.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2005 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_PROG_CONFIG_H
+#define DIRECT_PROG_CONFIG_H
+
+#include "direct.h"
+#include "progs/base/hardware_config.h"
+
+namespace Direct
+{
+
+class HardwareData : public ::Hardware::Data
+{
+public:
+ virtual void readConfig(GenericConfig &config);
+ virtual void writeConfig(GenericConfig &config) const;
+ virtual bool isEqual(const ::Hardware::Data &data) const;
+ HData data;
+};
+
+class Config : public ::Hardware::Config
+{
+public:
+ Config() : ::Hardware::Config("direct_programmer") {}
+
+protected:
+ virtual QStringList standardHardwareNames(PortType type) const;
+ virtual const ::Hardware::DataInfo *standardHardwareDataInfo(const QString &name) const;
+ virtual ::Hardware::Data *standardHardwareData(const QString &name) const;
+ virtual ::Hardware::Data *createHardwareData() const { return new HardwareData; }
+};
+
+} //namespace
+
+#endif
diff --git a/src/progs/direct/direct.pro b/src/progs/direct/direct.pro
new file mode 100644
index 0000000..60ac0f5
--- /dev/null
+++ b/src/progs/direct/direct.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = xml base
diff --git a/src/progs/direct/gui/Makefile.am b/src/progs/direct/gui/Makefile.am
new file mode 100644
index 0000000..ec7e698
--- /dev/null
+++ b/src/progs/direct/gui/Makefile.am
@@ -0,0 +1,5 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+libdirectui_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libdirectui.la
+libdirectui_la_SOURCES = direct_config_widget.cpp
diff --git a/src/progs/direct/gui/direct_config_widget.cpp b/src/progs/direct/gui/direct_config_widget.cpp
new file mode 100644
index 0000000..985cacd
--- /dev/null
+++ b/src/progs/direct/gui/direct_config_widget.cpp
@@ -0,0 +1,249 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "direct_config_widget.h"
+
+#include <qtooltip.h>
+#include <qcheckbox.h>
+#include <qtimer.h>
+#include <qpushbutton.h>
+
+#include "progs/direct/base/direct_prog_config.h"
+#include "progs/direct/base/direct_prog.h"
+
+//-----------------------------------------------------------------------------
+::Programmer::ConfigWidget *Direct::GroupUI::createConfigWidget(QWidget *parent) const
+{
+ return new ConfigWidget(static_cast<const ::Programmer::Group &>(group()), parent);
+}
+
+//-----------------------------------------------------------------------------
+const char * const INV_PIN_LABEL = I18N_NOOP("Check this option if your hardware uses negative logic for this pin.");
+const char * const DELAY_LABEL = I18N_NOOP("Some programming cards need low clock rate:\nadding delay to clock pulses might help.");
+
+Direct::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit)
+ : ::Hardware::HConfigWidget(base, parent, edit)
+{
+ // pins assignment
+ QGroupBox *groupb = new QGroupBox(1, Horizontal, i18n("Pin assignment"), this);
+ _mainVBox->addWidget(groupb);
+ QWidget *w = new QWidget(groupb);
+ QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10);
+ if (edit) grid->setColStretch(5, 1);
+ for (uint i=0; i<Nb_PinTypes; i++) {
+ QLabel *label = new QLabel(i18n(PIN_DATA[i].label), w);
+ QToolTip::add(label, PIN_DATA[i].comment);
+ grid->addWidget(label, i, 0);
+ _combos[i] = new QComboBox(w);
+ _combos[i]->setEnabled(edit);
+ connect(_combos[i], SIGNAL(activated(int)), SLOT(slotPinChanged()));
+ QToolTip::add(_combos[i], PIN_DATA[i].comment);
+ grid->addWidget(_combos[i], i, 1);
+ _invcbs[i] = new QCheckBox(i18n("Inverted"), w);
+ _invcbs[i]->setEnabled(edit);
+ QToolTip::add(_invcbs[i], i18n(INV_PIN_LABEL));
+ grid->addWidget(_invcbs[i], i, 2);
+ if (edit) {
+ _testcbs[i] = new QCheckBox(i18n("on"), w);
+ QToolTip::add(_testcbs[i], PIN_DATA[i].testComment);
+ connect(_testcbs[i], SIGNAL(clicked()), SLOT(slotTestPin()));
+ grid->addWidget(_testcbs[i], i, 3);
+ _testLabels[i] = new QLabel(w);
+ QToolTip::add(_testcbs[i], PIN_DATA[i].testComment);
+ grid->addWidget(_testLabels[i], i, 4);
+ updateTestStatus(PinType(i), false);
+ } else {
+ _testcbs[i] = 0;
+ _testLabels[i] = 0;
+ }
+ }
+
+ QHBoxLayout *hbox = new QHBoxLayout(_mainVBox);
+ QLabel *label = new QLabel(i18n("Clock delay"), this);
+ QToolTip::add(label, i18n(DELAY_LABEL));
+ hbox->addWidget(label);
+ _delay = new KIntNumInput(0, Horizontal, this);
+ _delay->setRange(0, 50, 5);
+ _delay->setEnabled(edit);
+ QToolTip::add(_delay, i18n(DELAY_LABEL));
+ hbox->addWidget(_delay);
+
+ if (edit) {
+ _sendBitsButton = new QPushButton(i18n("Send 0xA55A"), this);
+ _sendBitsButton->setToggleButton(true);
+ connect(_sendBitsButton, SIGNAL(clicked()), SLOT(sendBits()));
+ QToolTip::add(_sendBitsButton, i18n("Continuously send 0xA55A on \"Data out\" pin."));
+ _editVBox->addWidget(_sendBitsButton);
+ _editVBox->addStretch(1);
+ } else _sendBitsButton = 0;
+
+ // timer for sending bits
+ _timerSendBits = new QTimer(this);
+ connect(_timerSendBits, SIGNAL(timeout()), SLOT(slotSendBits()));
+
+ // timer for automatically polling DataOut pin
+ _timerPollDataOut = new QTimer(this);
+ connect(_timerPollDataOut, SIGNAL(timeout()), SLOT(updateDataIn()));
+}
+
+void Direct::HConfigWidget::sendBits()
+{
+ if ( _timerSendBits->isActive() ) {
+ _sendBitsButton->setText(i18n("Send 0xA55A"));
+ _timerSendBits->stop();
+ updateTestPin(DataOut);
+ } else {
+ _sendBitsButton->setText(i18n("Stop"));
+ _timerSendBits->start(1);
+ }
+}
+
+uint Direct::HConfigWidget::pin(PinType ptype) const
+{
+ return static_cast<const Hardware *>(_hardware)->pinForIndex(PIN_DATA[ptype].dir, _combos[ptype]->currentItem());
+}
+
+void Direct::HConfigWidget::slotPinChanged()
+{
+ for (uint i = 0; i<Nb_PinTypes; i++) {
+ if ( sender()!=_combos[i] ) continue;
+ updatePin(PinType(i));
+ }
+}
+
+void Direct::HConfigWidget::updatePin(PinType ptype)
+{
+ bool ground = hardware()->isGroundPin(pin(ptype));
+ _invcbs[ptype]->setEnabled(_edit);
+ if (ground) _invcbs[ptype]->hide();
+ else _invcbs[ptype]->show();
+ if (_edit) {
+ _testcbs[ptype]->setEnabled(PIN_DATA[ptype].dir==Port::Out && _connected);
+ _testLabels[ptype]->setEnabled(_connected);
+ if (ground) {
+ _testcbs[ptype]->hide();
+ _testLabels[ptype]->hide();
+ } else {
+ _testcbs[ptype]->show();
+ _testLabels[ptype]->show();
+ }
+ }
+}
+
+void Direct::HConfigWidget::slotTestPin()
+{
+ for (uint i = 0; i<Nb_PinTypes; i++) {
+ if ( sender()!=_testcbs[i] ) continue;
+ updateTestPin(PinType(i));
+ break;
+ }
+}
+
+void Direct::HConfigWidget::updateTestPin(PinType ptype)
+{
+ Q_ASSERT( _connected && ptype!=DataIn );
+ bool on = _testcbs[ptype]->isChecked();
+ hardware()->setPin(ptype, on);
+ updateTestStatus(ptype, on);
+ if ( ptype==Vpp ) updateDataIn();
+}
+
+void Direct::HConfigWidget::updateTestStatus(PinType ptype, bool on)
+{
+ if (on) _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].onLabel));
+ else _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].offLabel));
+}
+
+void Direct::HConfigWidget::updateDataIn()
+{
+ bool on = hardware()->readBit();
+ updateTestStatus(DataIn, on);
+ _testcbs[DataIn]->setChecked(on);
+}
+
+void Direct::HConfigWidget::sendBits(uint d, int nbb)
+{
+ Q_ASSERT(_connected);
+ hardware()->setWrite();
+ for (; nbb; --nbb) {
+ hardware()->setPin(Clock, High);
+ if ( d & 0x01 ) hardware()->setPin(DataOut, High);
+ else hardware()->setPin(DataOut, Low);
+ hardware()->setPin(Clock, Low);
+ d >>= 1; // Move the data over 1 bit
+ }
+ hardware()->setPin(DataOut, Low);
+ hardware()->setRead();
+}
+
+void Direct::HConfigWidget::slotSendBits()
+{
+ sendBits(0xA55A, 16);
+}
+
+bool Direct::HConfigWidget::set(const Port::Description &pd, const ::Hardware::Data &data)
+{
+ // connect port
+ _timerPollDataOut->stop();
+ if ( _timerSendBits->isActive() ) sendBits(); // stop
+ delete _hardware;
+ const HardwareData &hdata = static_cast<const HardwareData &>(data);
+ if ( pd.type==PortType::Serial ) _hardware = new SerialHardware(_base, pd.device, hdata);
+ else _hardware = new ParallelHardware(_base, pd.device, hdata);
+ bool ok = _hardware->connectHardware();
+ if ( !_edit) _hardware->disconnectHardware();
+ else _connected = ok;
+
+ // update GUI
+ if (_edit) {
+ for (uint i=0; i<Nb_PinTypes; i++) {
+ _testcbs[i]->setEnabled(_connected);
+ updateTestStatus(PinType(i), false);
+ }
+ if ( _connected ) _timerPollDataOut->start(100);
+ _sendBitsButton->setEnabled(_connected);
+ }
+
+ // update pins
+ for (uint i=0; i<Nb_PinTypes; i++) {
+ _combos[i]->clear();
+ Port::IODir dir = PIN_DATA[i].dir;
+ for (uint k=0; k<hardware()->nbPins(dir); k++)
+ _combos[i]->insertItem(hardware()->pinLabelForIndex(dir, k));
+ if (PIN_DATA[i].canBeGround) _combos[i]->insertItem("GND");
+ _combos[i]->setCurrentItem(hardware()->indexForPin(dir, hdata.data.pins[i]));
+ _invcbs[i]->setChecked(hdata.data.pins[i]<0);
+ updatePin(PinType(i));
+ }
+ _delay->setValue(hdata.data.clockDelay);
+
+ return ok;
+}
+
+Hardware::Data *Direct::HConfigWidget::data() const
+{
+ HardwareData *hdata = new HardwareData;
+ hdata->portType = _hardware->portDescription().type;
+ for (uint i=0; i<Nb_PinTypes; i++) {
+ hdata->data.pins[i] = pin(PinType(i));
+ if ( _invcbs[i]->isChecked() ) hdata->data.pins[i] = -hdata->data.pins[i];
+ }
+ hdata->data.clockDelay = _delay->value();
+ return hdata;
+}
+
+//-----------------------------------------------------------------------------
+Direct::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent)
+ : ::Hardware::ConfigWidget(new ::Direct::PicBase(group, 0), new Config, parent)
+{}
+
+Hardware::HConfigWidget *Direct::ConfigWidget::createHardwareConfigWidget(QWidget *parent, bool edit) const
+{
+ return new HConfigWidget(*_base, parent, edit);
+}
diff --git a/src/progs/direct/gui/direct_config_widget.h b/src/progs/direct/gui/direct_config_widget.h
new file mode 100644
index 0000000..4a5e4c6
--- /dev/null
+++ b/src/progs/direct/gui/direct_config_widget.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef DIRECT_CONFIG_WIDGET
+#define DIRECT_CONFIG_WIDGET
+
+#include <knuminput.h>
+
+#include "progs/gui/prog_group_ui.h"
+#include "progs/gui/hardware_config_widget.h"
+#include "progs/direct/base/direct.h"
+
+namespace Direct
+{
+//----------------------------------------------------------------------------
+class GroupUI : public ::Programmer::GroupUI
+{
+public:
+ virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const;
+ virtual bool hasAdvancedDialog() const { return false; }
+ virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; }
+};
+
+//-----------------------------------------------------------------------------
+class HConfigWidget : public ::Hardware::HConfigWidget
+{
+Q_OBJECT
+public:
+ HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit);
+ virtual bool set(const Port::Description &pd, const ::Hardware::Data &data);
+ virtual ::Hardware::Data *data() const;
+
+private slots:
+ void slotTestPin();
+ void slotPinChanged();
+ void updateDataIn();
+ void sendBits();
+ void slotSendBits();
+
+private:
+ QComboBox *_combos[Nb_PinTypes];
+ QCheckBox *_invcbs[Nb_PinTypes];
+ QCheckBox *_testcbs[Nb_PinTypes];
+ QLabel *_testLabels[Nb_PinTypes];
+ KIntNumInput *_delay;
+ QPushButton *_sendBitsButton;
+ QTimer *_timerSendBits, *_timerPollDataOut;
+
+ void sendBits(uint d, int nbb);
+ void updateTestPin(PinType ptype);
+ void updateTestStatus(PinType ptype, bool on);
+ uint pin(PinType ptype) const;
+ void updatePin(PinType ptype);
+ Hardware *hardware() { return static_cast<Hardware *>(_hardware); }
+};
+
+//-----------------------------------------------------------------------------
+class ConfigWidget : public ::Hardware::ConfigWidget
+{
+Q_OBJECT
+public:
+ ConfigWidget(const ::Programmer::Group &group, QWidget *parent);
+ virtual ::Hardware::HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const;
+};
+
+} // namespace
+
+#endif
diff --git a/src/progs/direct/xml/Makefile.am b/src/progs/direct/xml/Makefile.am
new file mode 100644
index 0000000..dd1f678
--- /dev/null
+++ b/src/progs/direct/xml/Makefile.am
@@ -0,0 +1,14 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+
+noinst_PROGRAMS = xml_direct_parser
+xml_direct_parser_SOURCES = xml_direct_parser.cpp
+OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \
+ $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \
+ $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \
+ $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \
+ $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \
+ $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \
+ $(top_builddir)/src/common/common/libcommon.la
+xml_direct_parser_DEPENDENCIES = $(OBJECTS)
+xml_direct_parser_LDADD = $(OBJECTS) $(LIB_KDECORE)
diff --git a/src/progs/direct/xml/xml.pro b/src/progs/direct/xml/xml.pro
new file mode 100644
index 0000000..740232e
--- /dev/null
+++ b/src/progs/direct/xml/xml.pro
@@ -0,0 +1,17 @@
+STOPDIR = ../../../..
+include($${STOPDIR}/app.pro)
+
+TARGET = xml_direct_parser
+SOURCES += xml_direct_parser.cpp
+LIBS += ../../../devices/list/libdevicelist.a \
+ ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \
+ ../../../devices/mem24/base/libmem24base.a \
+ ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \
+ ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \
+ ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \
+ ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a
+
+unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_direct_parser
+unix:QMAKE_CLEAN += ../base/direct_data.cpp
+win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_direct_parser.exe
+win32:QMAKE_CLEAN += ..\base\direct_data.cpp
diff --git a/src/progs/direct/xml/xml_direct_parser.cpp b/src/progs/direct/xml/xml_direct_parser.cpp
new file mode 100644
index 0000000..ee51674
--- /dev/null
+++ b/src/progs/direct/xml/xml_direct_parser.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * 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 "xml_to_data/prog_xml_to_data.h"
+#include "devices/pic/base/pic.h"
+#include "progs/direct/base/direct_data.h"
+
+namespace Direct
+{
+class XmlToData : public ::Programmer::XmlToData<Data>
+{
+public:
+ XmlToData() : ::Programmer::XmlToData<Data>("direct", "Direct") {}
+
+private:
+ virtual void parseData(QDomElement element, Data &data);
+ virtual void includes(QTextStream &s) const;
+ virtual void outputFunctions(QTextStream &s) const;
+};
+
+void Direct::XmlToData::parseData(QDomElement element, Data &)
+{
+ QString s = element.attribute("pwidth");
+ const Device::Data *d = Device::lister().data(currentDevice());
+ if ( d==0 ) qFatal("Invalid device name");
+}
+
+void Direct::XmlToData::includes(QTextStream &s) const
+{
+ Programmer::XmlToData<Data>::includes(s);
+ s << "#include \"direct_baseline.h\"" << endl;
+ s << "#include \"direct_16F.h\"" << endl;
+ s << "#include \"direct_18F.h\"" << endl;
+}
+
+void Direct::XmlToData::outputFunctions(QTextStream &s) const
+{
+ Programmer::XmlToData<Data>::outputFunctions(s);
+ s << "::Programmer::DeviceSpecific *Direct::Group::createDeviceSpecific(::Programmer::Base &base) const" << endl;
+ s << "{" << endl;
+ s << " uint i = family(static_cast<PicBase &>(base).device()->name());" << endl;
+ s << " switch(i) {" << endl;
+ for (uint i=0; i<uint(families().count()); i++) {
+ s << " case " + QString::number(i) + ": return new P" + families()[i] + "(base);" << endl;
+ }
+ s << " }" << endl;
+ s << " Q_ASSERT(false);" << endl;
+ s << " return 0;" << endl;
+ s << "}" << endl;
+}
+
+} // namespace
+
+//-----------------------------------------------------------------------------
+XML_MAIN(Direct::XmlToData)