From dd23a7cd93c90a1b5b659b8dfd146062c36933c0 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 15 Feb 2010 01:23:31 +0100 Subject: Add top-half implementation for m2764a EPROM Signed-off-by: Michael Buesch --- chip_m2764a.py | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ toprammer | 1 + 2 files changed, 188 insertions(+) create mode 100644 chip_m2764a.py 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 +# +# 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: -- cgit v1.2.3