summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chip_m2764a.py187
-rwxr-xr-xtoprammer1
2 files changed, 188 insertions, 0 deletions
diff --git a/chip_m2764a.py b/chip_m2764a.py
new file mode 100644
index 0000000..65aab81
--- /dev/null
+++ b/chip_m2764a.py
@@ -0,0 +1,187 @@
+"""
+# TOP2049 Open Source programming suite
+#
+# M2764A EPROM 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 M2764A(Chip):
+ PROGCMD_PPULSE = 1 # Perform a P-pulse
+
+ STAT_BUSY = 0x01 # Programmer is running a command
+
+ def __init__(self):
+ Chip.__init__(self, "m2764a", 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)
+
+ 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 readEEPROM(self):
+ self.top.cmdSetVCCXVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdSetVPPVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdLoadVCCXLayout(34)
+ self.top.cmdLoadVPPLayout(7)
+ self.top.cmdFlush()
+ self.top.cmdSetGNDPin(24)
+
+ image = ""
+ self.top.blockCommands()
+ self.printInfo("Reading EPROM ", newline=False)
+ self.__setEG(E=1, G=1)
+ for addr in range(0, 0x2000):
+ if addr % 192 == 0:
+ percent = (addr * 100 / 0x2000)
+ if percent % 25 == 0:
+ self.printInfo("%d%%" % percent, newline=False)
+ else:
+ self.printInfo(".", newline=False)
+
+ image += self.__readData(addr)
+ self.__setEG(E=1, G=1)
+ self.top.unblockCommands()
+ self.printInfo("100%")
+
+ return image
+
+ def writeEEPROM(self, image):
+ if len(image) != 0x2000:
+ self.throwError("Invalid EPROM image size %d (expected %d)" %\
+ (len(image), 0x2000))
+
+ self.top.cmdSetVCCXVoltage(5)
+ self.top.cmdFlush()
+ self.top.cmdSetVPPVoltage(12)
+ self.top.cmdFlush()
+ self.top.cmdLoadVCCXLayout(34)
+ self.top.cmdLoadVPPLayout(7)
+ self.top.cmdFlush()
+ self.top.cmdSetGNDPin(24)
+
+ self.top.blockCommands()
+ self.printInfo("Writing EPROM ", newline=False)
+ self.__setEG(E=1, G=1)
+ for addr in range(0, 0x2000):
+ if addr % 192 == 0:
+ percent = (addr * 100 / 0x2000)
+ if percent % 25 == 0:
+ self.printInfo("%d%%" % percent, newline=False)
+ else:
+ self.printInfo(".", newline=False)
+ self.__writeData(addr, ord(image[addr]))
+ self.__setEG(E=1, G=1)
+ self.top.unblockCommands()
+ self.printInfo("100%")
+
+ def __readData(self, addr):
+ self.__loadAddr(addr)
+ self.__setEG(E=0, G=0)
+ self.top.cmdFPGAReadByte()
+ stat = self.top.cmdReadStatusReg()
+ return stat[0]
+
+ def __writeData(self, addr, data):
+ self.__setEG(E=0, G=1)
+ self.__loadAddr(addr)
+ self.__loadData(data)
+ self.__loadPPulseLen(1)
+ self.__runCommandSync(self.PROGCMD_PPULSE)
+ for i in range(0, 25):
+ r = ord(self.__readData(addr))
+ if r == data:
+ break
+ self.__setEG(E=0, G=1)
+ self.__runCommandSync(self.PROGCMD_PPULSE)
+ else:
+ self.throwError("Failed to program 0x%04X (got 0x%02X, expected 0x%02X)" %\
+ (addr, r, data))
+ self.__setEG(E=0, G=1)
+ self.__loadPPulseLen(3 * (i + 1))
+ self.__runCommandSync(self.PROGCMD_PPULSE)
+
+ def __loadData(self, data):
+ self.top.cmdFPGAWrite(0x10, data)
+
+ def __loadCommand(self, command):
+ self.top.cmdFPGAWrite(0x12, command & 0xFF)
+
+ def __runCommandSync(self, command):
+ self.__loadCommand(command)
+ self.__busyWait()
+
+ def __loadAddrLow(self, addrLow):
+ self.top.cmdFPGAWrite(0x13, addrLow & 0xFF)
+
+ def __loadAddrHigh(self, addrHigh):
+ self.top.cmdFPGAWrite(0x14, addrHigh & 0xFF)
+
+ def __loadAddr(self, addr):
+ self.__loadAddrLow(addr)
+ self.__loadAddrHigh(addr >> 8)
+
+ def __loadPPulseLen(self, msec):
+ self.top.cmdFPGAWrite(0x15, msec)
+
+ def __setEG(self, E, G):
+ data = 0
+ if E:
+ data |= 1;
+ if G:
+ data |= 2;
+ self.top.cmdFPGAWrite(0x16, data)
+
+ 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):
+ for i in range(0, 100):
+ if not self.__busy():
+ return
+ time.sleep(0.01)
+ self.throwError("Timeout in busywait.")
+
+supportedChips.append(M2764A())
diff --git a/toprammer b/toprammer
index b2dc15c..ab9427f 100755
--- a/toprammer
+++ b/toprammer
@@ -38,6 +38,7 @@ except (ImportError), e:
# Import the supported chip modules
from chip_atmega8dip28 import *
from chip_m8cissp import *
+from chip_m2764a import *
class TOP:
bues.ch cgit interface