summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chip.py6
-rw-r--r--chip_m8cissp.py347
-rwxr-xr-xtoprammer17
3 files changed, 365 insertions, 5 deletions
diff --git a/chip.py b/chip.py
index 568dc6e..c635e78 100644
--- a/chip.py
+++ b/chip.py
@@ -26,14 +26,18 @@ from util import *
supportedChips = []
class Chip:
- def __init__(self, chipID):
+ def __init__(self, chipID, broken=False):
"The chipID is the ID string from the bitfile."
self.chipID = chipID
+ self.broken = broken
self.printPrefix = True
def getID(self):
return self.chipID
+ def isBroken(self):
+ return self.broken
+
def setTOP(self, top):
self.top = top
diff --git a/chip_m8cissp.py b/chip_m8cissp.py
new file mode 100644
index 0000000..80450f1
--- /dev/null
+++ b/chip_m8cissp.py
@@ -0,0 +1,347 @@
+"""
+# TOP2049 Open Source programming suite
+#
+# Cypress M8C In System Serial Programmer
+#
+# Copyright (c) 2010 Michael Buesch <mb@bu3sch.de>
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""
+
+from chip import *
+import time
+
+
+class M8C_ISSP(Chip):
+ ISSPCMD_POR = 1 # Perform a power-on-reset
+ ISSPCMD_PWROFF = 2 # Turn power off
+ ISSPCMD_SENDVEC = 3 # Send a vector
+ ISSPCMD_EXEC = 4 # Do an "execute" transfer
+
+ STAT_BUSY = 0x01 # Programmer is running a command
+
+ STRVEC_SETFREQ = {
+ 2 : "1001111110000000101000",
+ 3 : "1001111110000001001000",
+ 3.578 : "1001111110000001011000",
+ 4 : "1001111110000001101000",
+ 5 : "1001111110000010001000",
+ 6 : "1001111110000010101000",
+ 6.66666 : "1001111110000010111000",
+ 7 : "1001111110000011001000",
+ 8 : "1001111110000011100000",
+ 9 : "1001111110000100000000",
+ 10 : "1001111110000100100000",
+ 11 : "1001111110000101000000",
+ 12 : "1001111110000101100000",
+ }
+ STRVEC_INIT1 = (
+ "1100101000000000000000",
+ "0000000000000000000000",
+ "0000000000000000000000",
+ "1000111101100100000000",
+ "1101111011100000000000",
+ "1101111011000001000000",
+ "1001111100000111010000",
+ "1001111100100001011000",
+ "1101111010100000000000",
+ "1101111010000000011000",
+ "1001111101100100000000",
+ "1101111100100110000000",
+ "1101111101001000000000",
+ "1101111000000001000000",
+ "1101111100000000000000",
+ "1101111111100010010000",
+ )
+ STRVEC_INIT2 = (
+ "1101111011100000000000",
+ "1101111011000001000000",
+ "1001111100000111010000",
+ "1001111100100001011000",
+ "1101111010100000000000",
+ "1101111010000000011000",
+ "1001111101100100000000",
+ "1101111100100110000000",
+ "1101111101001000000000",
+ "1001111101000000001000",
+ "1101111000000000110000",
+ "1101111100000000000000",
+ "1101111111100010010000",
+ )
+ STRVEC_INIT3_HIVDD = (
+ "1101111011100000000000",
+ "1101111010000000011000",
+ "1101111010100000000000",
+ "1101111011000001000000",
+ "1101111100001010001000",
+ "1101111100111111100000",
+ "1101111101000110000000",
+ "1101111111100010010000",
+ "0000000000000000000000",
+ "1101111011100000000000",
+ "1101111010000000011000",
+ "1101111010100000000000",
+ "1101111011000001000000",
+ "1101111100001100000000",
+ "1101111100111101010000",
+ "1101111101000110000000",
+ "1101111011100010000000",
+ "1101111111100010010000",
+ "0000000000000000000000",
+ )
+ STRVEC_INIT3_LOVDD = (
+ "1101111011100000000000",
+ "1101111010000000011000",
+ "1101111010100000000000",
+ "1101111011000001000000",
+ "1101111100001010001000",
+ "1101111100111111000000",
+ "1101111101000110000000",
+ "1101111111100010010000",
+ "0000000000000000000000",
+ "1101111011100000000000",
+ "1101111010000000011000",
+ "1101111010100000000000",
+ "1101111011000001000000",
+ "1101111100001100000000",
+ "1101111100111101010000",
+ "1101111101000110000000",
+ "1101111011100010000000",
+ "1101111111100010010000",
+ "0000000000000000000000",
+ )
+ STRVEC_IDSETUP = (
+ "1101111011100000000000",
+ "1101111011000001000000",
+ "1001111100000111010000",
+ "1001111100100001011000",
+ "1101111010100000000000",
+ "1101111010000000011000",
+ "1001111101100100000000",
+ "1101111100100110000000",
+ "1101111101001000000000",
+ "1001111101000000000000",
+ "1101111000000000110000",
+ "1101111100000000000000",
+ "1101111111100010010000",
+ )
+ STRVEC_READBYTE = "101aaaaaaaaZDDDDDDDDZ0"
+ STRVEC_ERASEALL = (
+ "1101111011100000000000",
+ "1101111011001000000000",
+ "1001111100000111010000",
+ "1001111100101000011000",
+ "1101111010100000000000",
+ "1101111010000000011000",
+ "1001111101110000000000",
+ "1101111100100110000000",
+ "1101111101001000000000",
+ "1101111000000000101000",
+ "1101111100000000000000",
+ "1101111111100010010000",
+ )
+ STRVEC_SECURE = (
+ "1101111011100000000000",
+ "1101111011001000000000",
+ "1001111100000111010000",
+ "1001111100101000011000",
+ "1101111010100000000000",
+ "1101111010000000011000",
+ "1001111101110000000000",
+ "1101111100100110000000",
+ "1101111101001000000000",
+ "1101111000000000100000",
+ "1101111100000000000000",
+ "1101111111100010010000",
+ )
+
+ def __init__(self):
+ Chip.__init__(self, "m8c-issp", broken=True)
+
+ def initializeChip(self):
+ self.printDebug("Initializing chip")
+ self.top.cmdLoadVCCXLayout(0)
+ self.top.cmdLoadVPPLayout(0)
+ self.top.cmdSetGNDPin(0)
+ self.top.cmdSetVCCXVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdSetVPPVoltage(0)
+ self.top.cmdFlush()
+ self.top.cmdSetVPPVoltage(5)
+
+ #XXX
+ self.__powerOnReset()
+ id = self.__readID()
+ print "ID=0x%04X" % id
+
+ def shutdownChip(self):
+ self.printDebug("Shutdown chip")
+ self.top.cmdSetVCCXVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdSetVPPVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdLoadVCCXLayout(0)
+ self.top.cmdLoadVPPLayout(0)
+ self.top.cmdFlush()
+ self.top.cmdSetGNDPin(0)
+
+ def __powerDown(self):
+ "Turn the power to the device off"
+ self.printDebug("Powering device down...")
+ self.__runCommandSync(self.ISSPCMD_PWROFF)
+ self.top.flushCommands()
+ time.sleep(3)
+
+ def __powerOnReset(self):
+ "Perform a complete power-on-reset and initialization"
+ self.printDebug("Initializing supply power...")
+ self.top.cmdSetGNDPin(20)
+ self.top.cmdFlush()
+ self.top.cmdLoadVCCXLayout(17)
+ self.top.cmdFlush()
+ self.top.cmdSetVCCXVoltage(5)
+ self.top.cmdFlush()
+
+ self.__powerDown()
+ self.printDebug("Performing a power-on-reset...")
+ self.__loadStringVector(self.STRVEC_INIT1[0])
+ self.__runCommandSync(self.ISSPCMD_POR)
+ self.printDebug("Sending vector 1...")
+ for vec in self.STRVEC_INIT1[1:]:
+ self.__loadStringVector(vec)
+ self.__runCommandSync(self.ISSPCMD_SENDVEC)
+ self.printDebug("Executing...")
+ self.__runCommandSync(self.ISSPCMD_EXEC)
+ self.printDebug("Sending vector 2...")
+ for vec in self.STRVEC_INIT2:
+ self.__loadStringVector(vec)
+ self.__runCommandSync(self.ISSPCMD_SENDVEC)
+ self.printDebug("Executing...")
+ self.__runCommandSync(self.ISSPCMD_EXEC)
+ self.printDebug("Sending vector 3...")
+ for vec in self.STRVEC_INIT3_HIVDD:
+ self.__loadStringVector(vec)
+ self.__runCommandSync(self.ISSPCMD_SENDVEC)
+
+ def __readID(self):
+ "Read the silicon ID"
+ for vec in self.STRVEC_IDSETUP:
+ self.__loadStringVector(vec)
+ self.__runCommandSync(self.ISSPCMD_SENDVEC)
+ self.__runCommandSync(self.ISSPCMD_EXEC)
+
+ low = self.__readByte(0xF8)
+ high = self.__readByte(0xF9)
+
+ return low | (high << 8)
+
+ def __readByte(self, address):
+ strVec = self.__stringVectorReplace(self.STRVEC_READBYTE, "a", address)
+ self.__loadStringVector(strVec)
+ self.__runCommandSync(self.ISSPCMD_SENDVEC)
+ input = self.__getInputVector()
+ return (input >> 2) & 0xFF
+
+ def __loadCommand(self, command):
+ self.top.cmdFPGAWrite(0x12, command & 0xFF)
+
+ def __runCommandSync(self, command):
+ self.__loadCommand(command)
+ self.__busyWait()
+
+ def __loadVectorLow(self, vecLow):
+ self.top.cmdFPGAWrite(0x13, vecLow & 0xFF)
+
+ def __loadVectorMed(self, vecMed):
+ self.top.cmdFPGAWrite(0x14, vecMed & 0xFF)
+
+ def __loadVectorHigh(self, vecHigh):
+ self.top.cmdFPGAWrite(0x15, vecHigh & 0xFF)
+
+ def __loadVector(self, vec):
+ self.__loadVectorLow(vec)
+ self.__loadVectorMed(vec >> 8)
+ self.__loadVectorHigh(vec >> 16)
+
+ def __loadVectorInputMaskLow(self, maskLow):
+ self.top.cmdFPGAWrite(0x16, maskLow & 0xFF)
+
+ def __loadVectorInputMaskMed(self, maskMed):
+ self.top.cmdFPGAWrite(0x17, maskMed & 0xFF)
+
+ def __loadVectorInputMaskHigh(self, maskHigh):
+ self.top.cmdFPGAWrite(0x18, maskHigh & 0xFF)
+
+ def __loadVectorInputMask(self, mask):
+ self.__loadVectorInputMaskLow(mask)
+ self.__loadVectorInputMaskMed(mask >> 8)
+ self.__loadVectorInputMaskHigh(mask >> 16)
+
+ def __getStatusFlags(self):
+ self.top.cmdFPGAReadRaw(0x12)
+ stat = self.top.cmdReadStatusReg()
+ return ord(stat[0])
+
+ def __busy(self):
+ return bool(self.__getStatusFlags() & self.STAT_BUSY)
+
+ def __busyWait(self):
+#XXX for i in range(0, 50):
+ while 1:
+ if not self.__busy():
+ return
+ time.sleep(0.01)
+ self.throwError("Timeout in busywait. Chip not responding?")
+
+ def __getInputVector(self):
+ self.top.cmdFPGAReadRaw(0x13)
+ self.top.cmdFPGAReadRaw(0x14)
+ self.top.cmdFPGAReadRaw(0x15)
+ stat = self.top.cmdReadStatusReg()
+ return ord(stat[0]) | (ord(stat[1]) << 8) | (ord(stat[2]) << 16)
+
+ def __stringVectorToBinary(self, vector):
+ binary = 0
+ input = 0
+ assert(len(vector) == 22)
+ bit = len(vector) - 1
+ for b in vector:
+ if b == "1":
+ binary |= (1 << bit)
+ if b == "H" or b == "L" or b == "Z" or b == "D":
+ input |= (1 << bit)
+ bit -= 1
+ return (binary, input)
+
+ def __stringVectorReplace(self, strVec, replace, data):
+ ret = ""
+ for i in range(len(strVec) - 1, -1, -1):
+ b = strVec[i]
+ if b == replace:
+ if (data & 1):
+ ret = "1" + ret
+ else:
+ ret = "0" + ret
+ data >>= 1
+ else:
+ ret = b + ret
+ return ret
+
+ def __loadStringVector(self, strVec):
+ (vector, inputMask) = self.__stringVectorToBinary(strVec)
+ self.__loadVectorInputMask(inputMask)
+ self.__loadVector(vector)
+
+supportedChips.append(M8C_ISSP())
diff --git a/toprammer b/toprammer
index 2fd2a69..b2dc15c 100755
--- a/toprammer
+++ b/toprammer
@@ -37,16 +37,19 @@ except (ImportError), e:
# Import the supported chip modules
from chip_atmega8dip28 import *
+from chip_m8cissp import *
class TOP:
- def __init__(self, bitfileName, busDev=None, verbose=0, forceLevel=0, noqueue=False):
+ def __init__(self, bitfileName, busDev=None, verbose=0,
+ forceLevel=0, noqueue=False, usebroken=False):
"""bitfileName is the path to the .bit file.
busDev is a tuple (BUSID, DEVID) or None."""
self.verbose = verbose
self.forceLevel = forceLevel
self.noqueue = noqueue
+ self.usebroken = usebroken
self.commandsBlocked = False
self.commandQueue = []
@@ -59,6 +62,8 @@ class TOP:
if chipID.endswith(".ncd"):
chipID = chipID[0:-4]
self.chip = chipFind(chipID)
+ if self.chip and self.chip.isBroken() and not usebroken:
+ self.chip = None
if not self.chip:
raise TOPException("Did not find an implementation for the chip %s" % chipID)
self.chip.setTOP(self)
@@ -461,6 +466,7 @@ def usage():
print " -o|--force LEVEL Set the force level. Default = 0"
print " Note that any value greater than 0 may brick devices"
print " -Q|--noqueue Disable command queuing. Really slow!"
+ print " -B|--broken Also use broken algorithms"
def fileOut(filename, data):
if filename == "-":
@@ -482,14 +488,15 @@ def main(argv):
opt_action = None
opt_file = None
opt_noqueue = False
+ opt_usebroken = False
try:
(opts, args) = getopt.getopt(sys.argv[1:],
- "hb:d:V:Qs:xp:P:e:E:f:F:o:l:L:",
+ "hb:d:V:Qs:xp:P:e:E:f:F:o:l:L:B",
[ "help", "bitfile=", "device=", "verbose=", "noqueue",
"read-sig=", "erase", "read-prog=", "write-prog=",
"read-eeprom=", "write-eeprom=", "read-fuse=", "write-fuse=",
"read-lock=", "write-lock=",
- "force=", ])
+ "force=", "broken", ])
for (o, v) in opts:
if o in ("-h", "--help"):
usage()
@@ -509,6 +516,8 @@ def main(argv):
opt_forceLevel = int(v)
if o in ("-Q", "--noqueue"):
opt_noqueue = True
+ if o in ("-B", "--broken"):
+ opt_usebroken = True
if o in ("-s", "--read-sig"):
opt_action = "read-sig"
opt_file = v
@@ -551,7 +560,7 @@ def main(argv):
try:
top = TOP(bitfileName = opt_bitfile, busDev = opt_device,
verbose = opt_verbose, forceLevel = opt_forceLevel,
- noqueue = opt_noqueue)
+ noqueue = opt_noqueue, usebroken = opt_usebroken)
if opt_action == "read-sig":
fileOut(opt_file, top.readSignature())
elif opt_action == "erase":
bues.ch cgit interface