diff options
Diffstat (limited to 'src/progs/direct/base')
26 files changed, 3313 insertions, 0 deletions
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 |