123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- """
- # TOP2049 Open Source programming suite
- #
- # Cypress M8C In System Serial Programmer
- #
- # Copyright (c) 2010-2011 Michael Buesch <m@bues.ch>
- #
- # 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 libtoprammer.chip import *
- import time
- class Chip_M8C_ISSP(Chip):
- ISSPCMD_POR = 1 # Perform a power-on-reset
- ISSPCMD_PWROFF = 2 # Turn power off
- ISSPCMD_EXEC = 3 # Do an "execute" transfer
- STAT_BUSY0 = 0x01
- STAT_BUSY1 = 0x02
- STAT_ISSPSTATE = 0x1C
- STAT_ISSPSTATE_SHIFT = 2
- STAT_SDATA = 0x20
- STRVEC_INIT1 = (
- "1100101010000000000111",
- "0000000000000000000000",
- "0000000000000000000000",
- "0000000000000000000000",
- "0000000000000000000000",
- "0000000000000000000000",
- "1101111011100010000111",
- "1101111101000000000111",
- "1101111011100000000111",
- "1101111011100010000111",
- "1101111111000000100111",
- "1101110001000000100111",
- "1101110000000000011111",
- "1101111011100000000111",
- "1001111100000111010111",
- "1001111100100000011111",
- "1001111101101000000111",
- "1001111110000000000111",
- "1001111111001010110111",
- "1001111110100000001111",
- "1001111111100000001111",
- "1001111111110000000111",
- "1101111011100010000111",
- "1101110001000000000111",
- "1101111111000000000111",
- "1101110000000000000111",
- "1101111011100000000111",
- "1101111010000000011111",
- "1101111010100000000111",
- "1101111011000000000111",
- "1101111100000000000111",
- "1101111100100110000111",
- )
- STRVEC_INIT2 = (
- "1001111101000000000111",
- "1101111000000000110111",
- "1101111100000000000111",
- "1101111111100010010111",
- )
- STRVEC_IDSETUP = (
- "1101111011100010000111",
- "1101110000000000010111",
- "1101111011100010000111",
- "1101111101000000000111",
- "1101111011100000000111",
- "1101111011100010000111",
- "1101111111000000100111",
- "1101110001000000100111",
- "1101110000000000011111",
- "1101111011100000000111",
- "1001111100000111010111",
- "1001111100100000011111",
- "1001111101101000000111",
- "1001111110000000000111",
- "1001111111001010110111",
- "1001111110100000001111",
- "1001111111100000001111",
- "1001111111110000000111",
- "1101111011100010000111",
- "1101110001000000000111",
- "1101111111000000000111",
- "1101110000000000000111",
- "1101111011100000000111",
- "1101111010000000011111",
- "1101111010100000000111",
- "1101111011000000000111",
- "1101111100000000000111",
- "1101111100100110000111",
- "1001111101000000000111",
- "1101111000000000110111",
- "1101111100000000000111",
- "1101111111100010010111",
- )
- STRVEC_READBYTE = (
- "101aaaaaaaaZDDDDDDDDZ1",
- )
- STRVEC_WRITEBYTE = (
- "100aaaaaaaadddddddd111",
- )
- STRVEC_ERASEALL = (
- "1001111110000010101111",
- "1001111111001010110111",
- "1101111011100010000111",
- "1101111101000000000111",
- "1101111011100000000111",
- "1101111011100010000111",
- "1101111111000000100111",
- "1101110001000000100111",
- "1101110000000000011111",
- "1101111011100000000111",
- "1001111100000111010111",
- "1001111100100000011111",
- "1001111101101000000111",
- "1001111110000000000111",
- "1001111111001010110111",
- "1001111110100000001111",
- "1001111111100000001111",
- "1001111111110000000111",
- "1101111011100010000111",
- "1101110001000000000111",
- "1101111111000000000111",
- "1101110000000000000111",
- "1101111011100000000111",
- "1101111010000000011111",
- "1101111010100000000111",
- "1101111011000000000111",
- "1101111100000000000111",
- "1101111100100110000111",
- "1101111000000000101111",
- "1101111100000000000111",
- "1101111111100010010111",
- )
- STRVEC_SETBLKNUM = (
- "10011111010dddddddd111",
- )
- STRVEC_READBLK = (
- "1101111011100010000111",
- "1101111101000000000111",
- "1101111011100000000111",
- "1101111011100010000111",
- "1101111111000000100111",
- "1101110001000000100111",
- "1101110000000000011111",
- "1101111011100000000111",
- "1001111100000111010111",
- "1001111100100000011111",
- "1001111101101000000111",
- "1001111110000000000111",
- "1001111111001010110111",
- "1001111110100000001111",
- "1001111111100000001111",
- "1001111111110000000111",
- "1101111011100010000111",
- "1101110001000000000111",
- "1101111111000000000111",
- "1101110000000000000111",
- "1101111011100000000111",
- "1101111010000000011111",
- "1101111010100000000111",
- "1101111011000000000111",
- "1101111100000000000111",
- "1101111100100110000111",
- "1101111000000000001111",
- "1101111100000000000111",
- "1101111111100010010111",
- )
- STRVEC_WRITEBLK = (
- "1001111110001010100111",
- "1001111111001010110111",
- "1101111011100010000111",
- "1101111101000000000111",
- "1101111011100000000111",
- "1101111011100010000111",
- "1101111111000000100111",
- "1101110001000000100111",
- "1101110000000000011111",
- "1101111011100000000111",
- "1001111100000111010111",
- "1001111100100000011111",
- "1001111101101000000111",
- "1001111110000000000111",
- "1001111111001010110111",
- "1001111110100000001111",
- "1001111111100000001111",
- "1001111111110000000111",
- "1101111011100010000111",
- "1101110001000000000111",
- "1101111111000000000111",
- "1101110000000000000111",
- "1101111011100000000111",
- "1101111010000000011111",
- "1101111010100000000111",
- "1101111011000000000111",
- "1101111100000000000111",
- "1101111100100110000111",
- "1101111000000000010111",
- "1101111100000000000111",
- "1101111111100010010111",
- )
- STRVEC_READCHKSUM = (
- "10111111001ZDDDDDDDDZ1",
- "10111111000ZDDDDDDDDZ1",
- )
- STRVEC_READID = (
- "10111111000ZDDDDDDDDZ1",
- "10111111001ZDDDDDDDDZ1",
- )
- def __init__(self):
- Chip.__init__(self)
- # self.progmemSize = 1024 * 16
- self.progmemSize = 256#XXX
- def readSignature(self):
- self.progressMeterInit("Reading chip ID", 0)
- self.__powerOnReset()
- gotID = self.__readID()
- self.progressMeterFinish()
- return int2byte(gotID & 0xFF) + int2byte((gotID >> 8) & 0xFF)
- def erase(self):
- self.progressMeterInit("Erasing chip", 0)
- self.__powerOnReset()
- self.__bitbangStringVectors(self.STRVEC_ERASEALL)
- self.__runCommandSync(self.ISSPCMD_EXEC)
- self.progressMeterFinish()
- def writeProgmem(self, image):
- if len(image) > self.progmemSize or len(image) % 64 != 0:
- self.throwError("Invalid program memory image size %d "
- "(expected <=%d and multiple of 64)" %\
- (len(image), self.progmemSize))
- self.progressMeterInit("Writing program memory", len(image))
- self.__powerOnReset()
- for blknum in range(0, len(image) // 64):
- for i in range(0, 64):
- self.progressMeter(blknum * 64 + i)
- self.__writeByte(i, byte2int(image[blknum * 64 + i]))
- vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum)
- self.__bitbangStringVector(vec)
- self.__bitbangStringVectors(self.STRVEC_WRITEBLK)
- self.__runCommandSync(self.ISSPCMD_EXEC)
- self.progressMeterFinish()
- def readProgmem(self):
- self.progressMeterInit("Reading program memory", self.progmemSize)
- self.__powerOnReset()
- assert(self.progmemSize % 64 == 0)
- image = []
- for blknum in range(0, self.progmemSize // 64):
- vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum)
- self.__bitbangStringVector(vec)
- self.__bitbangStringVectors(self.STRVEC_READBLK)
- self.__runCommandSync(self.ISSPCMD_EXEC)
- for i in range(0, 64):
- self.progressMeter(blknum * 64 + i)
- image.append(int2byte(self.__readByte(i)))
- #FIXME return_code
- self.progressMeterFinish()
- return b"".join(image)
- def __powerDown(self):
- "Turn the power to the device off"
- self.printDebug("Powering device down...")
- self.__runCommandSync(self.ISSPCMD_PWROFF)
- self.top.hostDelay(5)
- def __powerOnReset(self):
- "Perform a complete power-on-reset and initialization"
- self.top.vcc.setLayoutMask(0)
- self.top.vpp.setLayoutMask(0)
- self.top.gnd.setLayoutMask(0)
- self.top.cmdSetVCCVoltage(5)
- self.top.cmdSetVPPVoltage(5)
- self.printDebug("Initializing supply power...")
- self.top.gnd.setLayoutPins( (20,) )
- self.top.vcc.setLayoutPins( (21,) )
- #FIXME when to do exec?
- self.__powerDown()
- self.printDebug("Performing a power-on-reset...")
- self.__uploadStringVector(self.STRVEC_INIT1[0])
- self.__runCommandSync(self.ISSPCMD_POR)
- self.printDebug("Sending vector 1...")
- self.__bitbangStringVectors(self.STRVEC_INIT1[1:])
- #XXX self.__runCommandSync(self.ISSPCMD_EXEC)
- self.printDebug("Sending vector 2...")
- self.__bitbangStringVectors(self.STRVEC_INIT2)
- self.__runCommandSync(self.ISSPCMD_EXEC)
- def __readID(self):
- "Read the silicon ID"
- self.__bitbangStringVectors(self.STRVEC_IDSETUP)
- self.__runCommandSync(self.ISSPCMD_EXEC)
- low = (self.__bitbangStringVector(self.STRVEC_READID[0]) >> 2) & 0xFF
- high = (self.__bitbangStringVector(self.STRVEC_READID[1]) >> 2) & 0xFF
- return low | (high << 8)
- def __readByte(self, address):
- vec = self.__stringVectorReplace(self.STRVEC_READBYTE[0], "a", address)
- inputData = self.__bitbangStringVector(vec)
- return (inputData >> 2) & 0xFF
- def __writeByte(self, address, byte):
- vec = self.__stringVectorReplace(self.STRVEC_WRITEBYTE[0], "a", address)
- vec = self.__stringVectorReplace(vec, "d", byte)
- self.__bitbangStringVector(vec)
- def __loadCommand(self, command):
- self.top.cmdFPGAWrite(0x11, command & 0xFF)
- def __runCommandSync(self, command):
- self.printDebug("Running synchronous command %d" % command)
- self.__loadCommand(command)
- self.__busyWait()
- def __setBitbang(self, SDATA, SDATA_in, SCLK, SCLK_z):
- value = 0
- if SDATA:
- value |= 0x01
- if SDATA_in:
- value |= 0x02
- if SCLK:
- value |= 0x04
- if SCLK_z:
- value |= 0x08
- self.top.cmdFPGAWrite(0x10, value)
- def __getStatusFlags(self):
- self.top.cmdFPGARead(0x10)
- stat = self.top.cmdReadBufferReg8()
- isspState = (stat & self.STAT_ISSPSTATE) >> self.STAT_ISSPSTATE_SHIFT
- sdata = bool(stat & self.STAT_SDATA)
- isBusy = bool(stat & self.STAT_BUSY0) != bool(stat & self.STAT_BUSY1)
- self.printDebug("isspState = 0x%02X, isBusy = %d, busyFlags = 0x%01X, sdata = %d" %\
- (isspState, isBusy, (stat & (self.STAT_BUSY0 | self.STAT_BUSY1)), sdata))
- return (isBusy, sdata, isspState)
- def __busy(self):
- (isBusy, sdata, isspState) = self.__getStatusFlags()
- return isBusy
- def __getSDATA(self):
- (isBusy, sdata, isspState) = self.__getStatusFlags()
- return int(sdata)
- def __busyWait(self):
- for i in range(0, 200):
- if not self.__busy():
- return
- self.top.hostDelay(0.01)
- self.throwError("Timeout in busywait. Chip not responding?")
- def __stringVectorToBinary(self, vector):
- binary = 0
- inputMask = 0
- assert(len(vector) == 22)
- bit = len(vector) - 1
- for b in vector:
- if b == "1":
- binary |= (1 << bit)
- elif b == "0":
- pass
- elif b == "H" or b == "L" or b == "Z" or b == "D":
- inputMask |= (1 << bit)
- else:
- assert(0)
- bit -= 1
- return (binary, inputMask)
- 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 __bitbangStringVector(self, strVec):
- vectorSize = len(strVec)
- (vector, inputMask) = self.__stringVectorToBinary(strVec)
- inputData = 0
- self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0)
- for i in range(vectorSize - 1, -1, -1):
- if inputMask & (1 << i):
- self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=1, SCLK_z=0)
- self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0)
- self.top.cmdDelay(0.000001)
- sdata = self.__getSDATA()
- inputData |= (sdata << i)
- else:
- self.__setBitbang(SDATA=(vector & (1 << i)), SDATA_in=0,
- SCLK=1, SCLK_z=0)
- self.__setBitbang(SDATA=0, SDATA_in=0, SCLK=0, SCLK_z=0)
- self.top.cmdDelay(0.000001)
- return inputData
- def __bitbangStringVectors(self, strVecList):
- for strVec in strVecList:
- self.__bitbangStringVector(strVec)
- def __uploadStringVector(self, strVec):
- (vector, inputMask) = self.__stringVectorToBinary(strVec)
- assert(inputMask == 0)
- self.top.cmdFPGAWrite(0x12, vector & 0xFF)
- self.top.cmdFPGAWrite(0x13, (vector >> 8) & 0xFF)
- self.top.cmdFPGAWrite(0x14, (vector >> 8) & 0xFF)
- ChipDescription(
- Chip_M8C_ISSP,
- bitfile = "m8c-issp",
- runtimeID = (0x0007, 0x01),
- chipVendors = "Cypress",
- description = "M8C In System Serial Programmer",
- packages = ( ("M8C ISSP header", "Special adapter"), ),
- comment = "Special adapter required",
- broken = True
- )
|