summaryrefslogtreecommitdiffstats
path: root/src/progs/direct/base/direct_30.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/progs/direct/base/direct_30.cpp')
-rw-r--r--src/progs/direct/base/direct_30.cpp261
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;
+}