From f508189682b6fba62e08feeb1596f682bad5fff9 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 18:42:24 +0000 Subject: Added KDE3 version of PikLab git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/piklab@1095639 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/progs/direct/base/Makefile.am | 13 + src/progs/direct/base/base.pro | 10 + src/progs/direct/base/direct.cpp | 394 +++++++++++++++++++++++++++ src/progs/direct/base/direct.h | 90 ++++++ src/progs/direct/base/direct.xml | 291 ++++++++++++++++++++ src/progs/direct/base/direct_16.cpp | 150 ++++++++++ src/progs/direct/base/direct_16.h | 46 ++++ src/progs/direct/base/direct_16F.cpp | 275 +++++++++++++++++++ src/progs/direct/base/direct_16F.h | 162 +++++++++++ src/progs/direct/base/direct_18.cpp | 109 ++++++++ src/progs/direct/base/direct_18.h | 34 +++ src/progs/direct/base/direct_18F.cpp | 318 +++++++++++++++++++++ src/progs/direct/base/direct_18F.h | 107 ++++++++ src/progs/direct/base/direct_30.cpp | 261 ++++++++++++++++++ src/progs/direct/base/direct_30.h | 44 +++ src/progs/direct/base/direct_baseline.cpp | 88 ++++++ src/progs/direct/base/direct_baseline.h | 68 +++++ src/progs/direct/base/direct_data.h | 21 ++ src/progs/direct/base/direct_mem24.cpp | 207 ++++++++++++++ src/progs/direct/base/direct_mem24.h | 47 ++++ src/progs/direct/base/direct_pic.cpp | 187 +++++++++++++ src/progs/direct/base/direct_pic.h | 68 +++++ src/progs/direct/base/direct_prog.cpp | 62 +++++ src/progs/direct/base/direct_prog.h | 74 +++++ src/progs/direct/base/direct_prog_config.cpp | 145 ++++++++++ src/progs/direct/base/direct_prog_config.h | 42 +++ 26 files changed, 3313 insertions(+) create mode 100644 src/progs/direct/base/Makefile.am create mode 100644 src/progs/direct/base/base.pro create mode 100644 src/progs/direct/base/direct.cpp create mode 100644 src/progs/direct/base/direct.h create mode 100644 src/progs/direct/base/direct.xml create mode 100644 src/progs/direct/base/direct_16.cpp create mode 100644 src/progs/direct/base/direct_16.h create mode 100644 src/progs/direct/base/direct_16F.cpp create mode 100644 src/progs/direct/base/direct_16F.h create mode 100644 src/progs/direct/base/direct_18.cpp create mode 100644 src/progs/direct/base/direct_18.h create mode 100644 src/progs/direct/base/direct_18F.cpp create mode 100644 src/progs/direct/base/direct_18F.h create mode 100644 src/progs/direct/base/direct_30.cpp create mode 100644 src/progs/direct/base/direct_30.h create mode 100644 src/progs/direct/base/direct_baseline.cpp create mode 100644 src/progs/direct/base/direct_baseline.h create mode 100644 src/progs/direct/base/direct_data.h create mode 100644 src/progs/direct/base/direct_mem24.cpp create mode 100644 src/progs/direct/base/direct_mem24.h create mode 100644 src/progs/direct/base/direct_pic.cpp create mode 100644 src/progs/direct/base/direct_pic.h create mode 100644 src/progs/direct/base/direct_prog.cpp create mode 100644 src/progs/direct/base/direct_prog.h create mode 100644 src/progs/direct/base/direct_prog_config.cpp create mode 100644 src/progs/direct/base/direct_prog_config.h (limited to 'src/progs/direct/base') 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 * + * Copyright (C) 2003-2004 Alain Gibaud * + * 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 + +#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 v = _port->pinData(dir); + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + for (uint i=0; iisGroundPin(p); +} + +bool Direct::operator !=(const HData &d1, const HData &d2) +{ + for (uint i=0; i> 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" <> 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"<> 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"<> 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"<> 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"<> 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." <> 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" <chip)"<> " ; + 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>= 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 * + * Copyright (C) 2003-2004 Alain Gibaud * + * 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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; iactions & ::Programmer::OnlyProgrammedVerify; + const Device::Array wdata = static_cast(vdata->memory).arrayForWriting(type); + if (only) nbWords = findNonMaskEnd(type, wdata)+1; + } + BitValue mask = device().mask(type); + for (uint i = 0; i * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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 * + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2004 Keith Baker [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 * + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2004 Keith Baker [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 * + * * + * 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 * + * * + * 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 * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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> 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(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> 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 * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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 * + * * + * 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 * + * * + * 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 * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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 * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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 * + * * + * 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 * + * * + * 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 + +#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=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; i200 ) { // 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 * + * * + * 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(*_base.hardware()); } + const Mem24::Data &device() const { return static_cast(*::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 * + * * + * 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()) * + * * + * 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(*_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 * + * * + * 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(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(data)); + return new Mem24Base(*this, static_cast(data)); +} + +::Programmer::Hardware *Direct::DGroup::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + Config config; + HardwareData *hdata = static_cast(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(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 * + * * + * 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); } +}; + +//---------------------------------------------------------------------------- +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); } +}; + +//---------------------------------------------------------------------------- +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 * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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: htpp://k9spud.com/hoodmicro") }, + { 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).

Webpage: http://www.epemag.wimborne.co.uk/1001.htm") }, + { 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(cdata).data; + if ( data.clockDelay!=hdata.clockDelay ) return false; + for (uint i=0; iname = 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 * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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 -- cgit v1.2.1