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