diff options
Diffstat (limited to 'src/progs/direct/base/direct_16.cpp')
-rw-r--r-- | src/progs/direct/base/direct_16.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
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; +} |