From 46b4d210eb05b659761681362a636025514ff4e6 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 16 Jun 2013 20:36:00 +0200 Subject: Add support for more Microchip and Atmel microcontrollers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation by Pavel Štemberk Signed-off-by: Michael Buesch --- libtoprammer/chip.py | 41 +- libtoprammer/chips/__init__.py | 6 +- libtoprammer/chips/at89s51dip40.py | 322 +++++++++++++++ libtoprammer/chips/at89s52dip40.py | 321 +++++++++++++++ libtoprammer/chips/microchip01/__init__.py | 6 + .../chips/microchip01/microchip01_common.py | 425 +++++++++++++++++++ libtoprammer/chips/microchip01/pic10f200dip8.py | 83 ++++ libtoprammer/chips/microchip01/pic10f202dip8.py | 81 ++++ libtoprammer/chips/microchip01/pic12f508dip8.py | 75 ++++ libtoprammer/chips/microchip01/pic16f59sip6.py | 81 ++++ libtoprammer/chips/microchip02/__init__.py | 5 + .../chips/microchip02/microchip02_common.py | 449 +++++++++++++++++++++ libtoprammer/chips/microchip02/pic10f322dip8.py | 86 ++++ libtoprammer/chips/microchip02/pic12f1822dip8.py | 103 +++++ libtoprammer/chips/microchip02/pic16f1824dip14.py | 103 +++++ libtoprammer/chips/microchip_common.py | 353 ---------------- libtoprammer/chips/pic10f200dip8.py | 61 --- libtoprammer/chips/pic10f202dip8.py | 60 --- libtoprammer/fpga/bin/at89s5xdip40.bit | Bin 0 -> 24789 bytes libtoprammer/fpga/bin/microchip01dip14dip20.bit | Bin 0 -> 24798 bytes libtoprammer/fpga/bin/microchip01dip18.bit | Bin 0 -> 24793 bytes libtoprammer/fpga/bin/microchip01dip8.bit | Bin 0 -> 24792 bytes libtoprammer/fpga/bin/microchip01sip6.bit | Bin 0 -> 24792 bytes libtoprammer/fpga/bin/pic10fXXXdip8.bit | Bin 24790 -> 0 bytes libtoprammer/fpga/bin/pic10fxxxdip8.bit | Bin 0 -> 24790 bytes libtoprammer/fpga/src/at89s5xdip40/Makefile | 2 + .../fpga/src/at89s5xdip40/at89s5xdip40.ucf | 62 +++ libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.v | 326 +++++++++++++++ libtoprammer/fpga/src/microchip01/microchip01.vh | 148 +++++++ .../src/microchip01/microchip01dip14dip20/Makefile | 3 + .../microchip01dip14dip20/microchip01dip14dip20.v | 76 ++++ .../fpga/src/microchip01/microchip01dip18/Makefile | 3 + .../microchip01dip18/microchip01dip18.v | 76 ++++ .../fpga/src/microchip01/microchip01dip8/Makefile | 3 + .../microchip01/microchip01dip8/microchip01dip8.v | 54 +++ .../fpga/src/microchip01/microchip01sip6/Makefile | 3 + .../microchip01/microchip01sip6/microchip01sip6.v | 51 +++ .../fpga/src/microchip01/pic10fxxxdip8/Makefile | 3 + .../src/microchip01/pic10fxxxdip8/pic10fxxxdip8.v | 51 +++ libtoprammer/fpga/src/pic10fXXXdip8/Makefile | 2 - .../fpga/src/pic10fXXXdip8/pic10fXXXdip8.v | 174 -------- libtoprammer/main.py | 17 + libtoprammer/util.py | 15 +- toprammer | 45 ++- toprammer-gui | 55 ++- 45 files changed, 3136 insertions(+), 694 deletions(-) create mode 100644 libtoprammer/chips/at89s51dip40.py create mode 100644 libtoprammer/chips/at89s52dip40.py create mode 100644 libtoprammer/chips/microchip01/__init__.py create mode 100644 libtoprammer/chips/microchip01/microchip01_common.py create mode 100644 libtoprammer/chips/microchip01/pic10f200dip8.py create mode 100644 libtoprammer/chips/microchip01/pic10f202dip8.py create mode 100644 libtoprammer/chips/microchip01/pic12f508dip8.py create mode 100644 libtoprammer/chips/microchip01/pic16f59sip6.py create mode 100644 libtoprammer/chips/microchip02/__init__.py create mode 100644 libtoprammer/chips/microchip02/microchip02_common.py create mode 100644 libtoprammer/chips/microchip02/pic10f322dip8.py create mode 100644 libtoprammer/chips/microchip02/pic12f1822dip8.py create mode 100644 libtoprammer/chips/microchip02/pic16f1824dip14.py delete mode 100644 libtoprammer/chips/microchip_common.py delete mode 100644 libtoprammer/chips/pic10f200dip8.py delete mode 100644 libtoprammer/chips/pic10f202dip8.py create mode 100644 libtoprammer/fpga/bin/at89s5xdip40.bit create mode 100644 libtoprammer/fpga/bin/microchip01dip14dip20.bit create mode 100644 libtoprammer/fpga/bin/microchip01dip18.bit create mode 100644 libtoprammer/fpga/bin/microchip01dip8.bit create mode 100644 libtoprammer/fpga/bin/microchip01sip6.bit delete mode 100644 libtoprammer/fpga/bin/pic10fXXXdip8.bit create mode 100644 libtoprammer/fpga/bin/pic10fxxxdip8.bit create mode 100644 libtoprammer/fpga/src/at89s5xdip40/Makefile create mode 100644 libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.ucf create mode 100644 libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.v create mode 100644 libtoprammer/fpga/src/microchip01/microchip01.vh create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip14dip20/Makefile create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip14dip20/microchip01dip14dip20.v create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip18/Makefile create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip18/microchip01dip18.v create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip8/Makefile create mode 100644 libtoprammer/fpga/src/microchip01/microchip01dip8/microchip01dip8.v create mode 100644 libtoprammer/fpga/src/microchip01/microchip01sip6/Makefile create mode 100644 libtoprammer/fpga/src/microchip01/microchip01sip6/microchip01sip6.v create mode 100644 libtoprammer/fpga/src/microchip01/pic10fxxxdip8/Makefile create mode 100644 libtoprammer/fpga/src/microchip01/pic10fxxxdip8/pic10fxxxdip8.v delete mode 100644 libtoprammer/fpga/src/pic10fXXXdip8/Makefile delete mode 100644 libtoprammer/fpga/src/pic10fXXXdip8/pic10fXXXdip8.v diff --git a/libtoprammer/chip.py b/libtoprammer/chip.py index c53f04c..7a37c37 100644 --- a/libtoprammer/chip.py +++ b/libtoprammer/chip.py @@ -40,6 +40,8 @@ class Chip: SUPPORT_RAMREAD = (1 << 10) SUPPORT_RAMWRITE = (1 << 11) SUPPORT_TEST = (1 << 12) + SUPPORT_UILREAD = (1 << 13) + SUPPORT_UILWRITE = (1 << 14) @classmethod def chipSupportsAttr(cls, methodName): @@ -54,19 +56,22 @@ class Chip: "Get the SUPPORT_... flags for this chip" flags = 0 for (methodName, flag) in ( - ("erase", Chip.SUPPORT_ERASE), - ("readSignature", Chip.SUPPORT_SIGREAD), - ("readProgmem", Chip.SUPPORT_PROGMEMREAD), - ("writeProgmem", Chip.SUPPORT_PROGMEMWRITE), - ("readEEPROM", Chip.SUPPORT_EEPROMREAD), - ("writeEEPROM", Chip.SUPPORT_EEPROMWRITE), - ("readFuse", Chip.SUPPORT_FUSEREAD), - ("writeFuse", Chip.SUPPORT_FUSEWRITE), - ("readLockbits", Chip.SUPPORT_LOCKREAD), - ("writeLockbits", Chip.SUPPORT_LOCKWRITE), - ("readRAM", Chip.SUPPORT_RAMREAD), - ("writeRAM", Chip.SUPPORT_RAMWRITE), - ("test", Chip.SUPPORT_TEST)): + ("erase", cls.SUPPORT_ERASE), + ("readSignature", cls.SUPPORT_SIGREAD), + ("readProgmem", cls.SUPPORT_PROGMEMREAD), + ("writeProgmem", cls.SUPPORT_PROGMEMWRITE), + ("readEEPROM", cls.SUPPORT_EEPROMREAD), + ("writeEEPROM", cls.SUPPORT_EEPROMWRITE), + ("readFuse", cls.SUPPORT_FUSEREAD), + ("writeFuse", cls.SUPPORT_FUSEWRITE), + ("readLockbits", cls.SUPPORT_LOCKREAD), + ("writeLockbits", cls.SUPPORT_LOCKWRITE), + ("readRAM", cls.SUPPORT_RAMREAD), + ("writeRAM", cls.SUPPORT_RAMWRITE), + ("test", cls.SUPPORT_TEST), + ("readUserIdLocation", cls.SUPPORT_UILREAD), + ("writeUserIdLocation", cls.SUPPORT_UILWRITE)): + if cls.chipSupportsAttr(methodName): flags |= flag return flags @@ -241,6 +246,14 @@ class Chip: def writeRAM(self, image): # Override me in the subclass, if required. self.throwError("RAM writing not supported") + + def readUserIdLocation(self): + # Override me in the subclass, if required. + self.throwError("User ID Location reading not supported") + + def writeUserIdLocation(self, image): + # Override me in the subclass, if required. + self.throwError("User ID Location writing not supported") __registeredChips = [] @@ -497,6 +510,8 @@ class ChipDescription: (Chip.SUPPORT_RAMREAD, "RAM reading"), (Chip.SUPPORT_RAMWRITE, "RAM writing"), (Chip.SUPPORT_TEST, "Unit-testing"), + (Chip.SUPPORT_UILMREAD, "User ID Location reading"), + (Chip.SUPPORT_UILWRITE, "User ID Location writing"), ) supportFlags = self.chipImplClass.getSupportFlags() for (flag, description) in supportedFeatures: diff --git a/libtoprammer/chips/__init__.py b/libtoprammer/chips/__init__.py index a90351b..9efbb02 100644 --- a/libtoprammer/chips/__init__.py +++ b/libtoprammer/chips/__init__.py @@ -3,6 +3,8 @@ from _27cxxx import * from _74hc4094 import * from at89c2051dip20 import * +from at89s51dip40 import * +from at89s52dip40 import * from atmega32dip40 import * from atmega88dip28 import * from atmega8dip28 import * @@ -11,7 +13,7 @@ from attiny26dip20 import * from hm62256dip28 import * from m24cxxdip8 import * from m8cissp import * -from pic10f200dip8 import * -from pic10f202dip8 import * from unitest import * from w29ee011dip32 import * +from microchip01 import * +from microchip02 import * diff --git a/libtoprammer/chips/at89s51dip40.py b/libtoprammer/chips/at89s51dip40.py new file mode 100644 index 0000000..e9327be --- /dev/null +++ b/libtoprammer/chips/at89s51dip40.py @@ -0,0 +1,322 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel AT89C2051 DIP20 Support +# +# Copyright (c) 2010 Guido +# 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 libtoprammer.chip import * + + +class Chip_AT89S51dip40(Chip): + STAT_BUSY = 0x01 # Programmer is running a command + STAT_ERR = 0x02 # Error during write + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP40", + chipPinVCC = 40, + chipPinsVPP = 31, + chipPinGND = 20) + self.flashPageSize = 0x2000 + self.flashPages = 1 + + def __initChip(self): + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(True) + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(5) + + def readSignature(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__loadAddress(0x0100) + self.__setPx() + data = "" + self.top.cmdFPGARead(0x10) + self.__loadAddress(0x0200) + self.top.cmdFPGARead(0x10) + data += self.top.cmdReadBufferReg() + self.applyVPP(False) + self.__loadCommand(6) # VPP off + signature = "" + signature += data[0] + signature += data[1] + self.top.printInfo("Signature: %X, %X" % (byte2int(signature[0]), byte2int(signature[1]))) + return signature + + def erase(self): + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.top.cmdDelay(0.5) + self.__setPx(P26=1, P33=1) + self.top.cmdSetVPPVoltage(12) + self.__runCommandSync(3) + self.top.cmdDelay(0.5) + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + self.top.flushCommands() + self.top.printInfo("{chipid}: Erasing flash, verifying ...".format(chipid=self.chipDescription.chipID)) + ok = self.__verifyErase() + if ok == 0: + self.top.printInfo("{chipid}: Erase done.".format(chipid=self.chipDescription.chipID)) + else: + self.top.printInfo("{chipid}: Erase failed!".format(chipid=self.chipDescription.chipID)) + + def readProgmem(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__setPx(P36=1, P37=1) + #self.__setPx(P26=1, P27=1, P36=1) + #self.__setPx() + image = "" + byteCount = 0 + self.progressMeterInit("Reading Flash", self.flashPageSize*self.flashPages) + for addr in range(0, self.flashPageSize*self.flashPages): + self.progressMeter(addr) + self.__loadAddress(addr) + #self.__runCommandSync(4) + self.top.cmdFPGARead(0x10) + byteCount += 1 + if byteCount == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(byteCount) + byteCount = 0 + image += self.top.cmdReadBufferReg(byteCount) + self.applyVPP(False) + self.__setPx() + self.__loadCommand(6) # VPP off + self.top.flushCommands() + self.progressMeterFinish() + + return image + + def writeProgmem(self, image): + if len(image) > self.flashPageSize*self.flashPages: + self.throwError("Invalid FLASH image size %d (expected <=%d)" %\ + (len(image), self.flashPageSize*self.flashPages)) + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__setPx(P27=1, P33=1, P36=1, P37=1) + self.top.cmdSetVPPVoltage(12) + self.progressMeterInit("Writing Flash", len(image)) + for addr in range(0, len(image)): + self.progressMeter(addr) + data = byte2int(image[addr]) + if data != 0xFF: + self.__loadData(data) + self.__loadAddress(addr) + self.__loadCommand(3) + ok = self.__progWait() + if (ok & self.STAT_ERR) != 0: + self.throwError("Write byte failed.") + self.top.flushCommands() + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + self.progressMeterFinish() + ok = self.__verifyProgmem(image) + if ok == 0: + self.top.printInfo("{chipid}: Write flash done.".format(chipid = self.chipDescription.chipID)) + else: + self.top.printInfo("{chipid}: Write flash failed!".format(chipid = self.chipDescription.chipID)) + + def readLockbits(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__setPx(P26=1, P27=1, P36=1) + data = "" + self.top.cmdFPGARead(0x10) + data += self.top.cmdReadBufferReg() + self.applyVPP(False) + self.__loadCommand(6) # VPP off + lockbits = "" + lockbits += data[0] + return lockbits + + def writeLockbits(self, image): + if len(image) != 1: + self.throwError("Invalid lock-bits image size %d (expected %d)" %\ + (len(image), 1)) + self.progressMeterInit("Writing lock bits", 3) + lbMask = 0x04 + lb=byte2int(image[0]) + if(lb & lbMask ): + self.progressMeter(1) + self.__writeLockbit(1) + lbMask <<= 1 + if(lb & lbMask ): + self.progressMeter(2) + self.__writeLockbit(2) + lbMask <<= 1 + if(lb & lbMask ): + self.progressMeter(3) + self.__writeLockbit(3) + self.progressMeterFinish() + + def __writeLockbit(self, lb): + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.top.cmdSetVPPVoltage(12) + if(lb == 1 ): + self.__setPx(P26=1, P27=1, P33=1, P36=1, P37=1) + self.__runCommandSync(3) + elif(lb == 2 ): + self.__setPx(P26=1, P27=1, P33=1, P36=0, P37=0) + self.__runCommandSync(3) + elif(lb == 3 ): + self.__setPx(P26=1, P27=0, P33=1, P36=1, P37=0) + self.__runCommandSync(3) + self.top.flushCommands() + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + + def __verifyErase(self): + ok = 0 + image = self.readProgmem() + for addr in range(0, self.flashPageSize*self.flashPages): + if byte2int(image[addr]) != 0xFF: + ok = 1 + return ok + + def __verifyProgmem(self,image): + data = self.readProgmem() + ok = 0 + for addr in range(0, len(image)-1): + if byte2int(image[addr]) != byte2int(data[addr]): + ok = 1 + return ok + + def __loadData(self, data): + self.top.cmdFPGAWrite(0x10, data) + + def __loadAddress(self, addr): + self.top.cmdFPGAWrite(0x11, addr & 0x00FF) + self.top.cmdFPGAWrite(0x12, (addr >> 8) & 0x3FFF) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x13, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setPx(self, P26=0, P27=0, P33=0, P36=0, P37=0, nPSEN=0, RST=1): + data = 0 + if P26: + data |= 1 + if P27: + data |= 2 + if P33: + data |= 4 + if P36: + data |= 8 + if P37: + data |= 16 + if nPSEN: + data |= 32 + if RST: + data |= 64 + self.top.cmdFPGAWrite(0x16, data) + + def __getStatusFlags(self): + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + return byte2int(stat[0]) + + def __busy(self): + return bool(self.__getStatusFlags() & self.STAT_BUSY) + + def __busyWait(self): + for i in range(0, 26): + if not self.__busy(): + return + self.top.hostDelay(0.001) + self.throwError("Timeout in busywait.") + + def __progWait(self): + for i in range(0,4): + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + if (byte2int(stat[0]) & self.STAT_BUSY) == 0: + return byte2int(stat[0]) + self.top.hostDelay(0.001) + self.throwError("Timeout in busywait.") +lockbitDesc = ( + BitDescription(0, "Unused"), + BitDescription(1, "Unused"), + BitDescription(2, "BLB01 - further programming of flash mem. is disabled"), + BitDescription(3, "BLB02 - verify disabled"), + BitDescription(4, "BLB03 - external execution disabled"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), +) + +ChipDescription( + Chip_AT89S51dip40, + bitfile = "at89s5xdip40", + chipID = "at89s51dip40", + runtimeID = (0x0005, 0x01), + chipVendors = "Atmel", + description = "AT89S51", + lockbitDesc = lockbitDesc, + maintainer = None, + packages = ( ("DIP40", ""), ) +) diff --git a/libtoprammer/chips/at89s52dip40.py b/libtoprammer/chips/at89s52dip40.py new file mode 100644 index 0000000..238a50a --- /dev/null +++ b/libtoprammer/chips/at89s52dip40.py @@ -0,0 +1,321 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel AT89C2051 DIP20 Support +# +# Copyright (c) 2010 Guido +# 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 libtoprammer.chip import * + + +class Chip_AT89S52dip40(Chip): + STAT_BUSY = 0x01 # Programmer is running a command + STAT_ERR = 0x02 # Error during write + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP40", + chipPinVCC = 40, + chipPinsVPP = 31, + chipPinGND = 20) + self.flashPageSize = 0x4000 + self.flashPages = 1 + + def __initChip(self): + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(True) + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(5) + + def readSignature(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__loadAddress(0x0100) + self.__setPx() + data = "" + self.top.cmdFPGARead(0x10) + self.__loadAddress(0x0200) + self.top.cmdFPGARead(0x10) + data += self.top.cmdReadBufferReg() + self.applyVPP(False) + self.__loadCommand(6) # VPP off + signature = "" + signature += data[0] + signature += data[1] + self.top.printInfo("Signature: %X, %X" % (byte2int(signature[0]), byte2int(signature[1]))) + return signature + + def erase(self): + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.top.cmdDelay(0.5) + self.__setPx(P26=1, P33=1) + self.top.cmdSetVPPVoltage(12) + self.__runCommandSync(3) + self.top.cmdDelay(0.5) + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + self.top.flushCommands() + self.top.printInfo("{chipid}: Erasing flash, verifying ...".format(chipid=self.chipDescription.chipID)) + ok = self.__verifyErase() + if ok == 0: + self.top.printInfo("{chipid}: Erase done.".format(chipid=self.chipDescription.chipID)) + else: + self.top.printInfo("{chipid}: Erase failed!".format(chipid=self.chipDescription.chipID)) + + def readProgmem(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__setPx(P36=1, P37=1) + #self.__setPx(P26=1, P27=1, P36=1) + #self.__setPx() + image = "" + byteCount = 0 + self.progressMeterInit("Reading Flash", self.flashPageSize*self.flashPages) + for addr in range(0, self.flashPageSize*self.flashPages): + self.progressMeter(addr) + self.__loadAddress(addr) + #self.__runCommandSync(4) + self.top.cmdFPGARead(0x10) + byteCount += 1 + if byteCount == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(byteCount) + byteCount = 0 + image += self.top.cmdReadBufferReg(byteCount) + self.applyVPP(False) + self.__setPx() + self.__loadCommand(6) # VPP off + self.top.flushCommands() + self.progressMeterFinish() + + return image + + def writeProgmem(self, image): + if len(image) > self.flashPageSize*self.flashPages: + self.throwError("Invalid FLASH image size %d (expected <=%d)" %\ + (len(image), self.flashPageSize*self.flashPages)) + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__setPx(P27=1, P33=1, P36=1, P37=1) + self.top.cmdSetVPPVoltage(12) + self.progressMeterInit("Writing Flash", len(image)) + for addr in range(0, len(image)): + self.progressMeter(addr) + data = byte2int(image[addr]) + if data != 0xFF: + self.__loadData(data) + self.__loadAddress(addr) + self.__loadCommand(3) + ok = self.__progWait() + if (ok & self.STAT_ERR) != 0: + self.throwError("Write byte failed.") + self.top.flushCommands() + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + self.progressMeterFinish() + ok = self.__verifyProgmem(image) + if ok == 0: + self.top.printInfo("{chipid}: Write flash done.".format(chipid = self.chipDescription.chipID)) + else: + self.top.printInfo("{chipid}: Write flash failed!".format(chipid = self.chipDescription.chipID)) + + def readLockbits(self): + self.__initChip() + self.top.cmdEnableZifPullups(True) + self.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.__loadCommand(1) # set nPROG + self.__setPx(P26=1, P27=1, P36=1) + data = "" + self.top.cmdFPGARead(0x10) + data += self.top.cmdReadBufferReg() + self.applyVPP(False) + self.__loadCommand(6) # VPP off + lockbits = "" + lockbits += data[0] + return lockbits + + def writeLockbits(self, image): + if len(image) != 1: + self.throwError("Invalid lock-bits image size %d (expected %d)" %\ + (len(image), 1)) + self.progressMeterInit("Writing lock bits", 3) + lbMask = 0x04 + lb=byte2int(image[0]) + if(lb & lbMask ): + self.progressMeter(1) + self.__writeLockbit(1) + lbMask <<= 1 + if(lb & lbMask ): + self.progressMeter(2) + self.__writeLockbit(2) + lbMask <<= 1 + if(lb & lbMask ): + self.progressMeter(3) + self.__writeLockbit(3) + self.progressMeterFinish() + + def __writeLockbit(self, lb): + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.applyVPP(True) + self.top.cmdSetVPPVoltage(12) + if(lb == 1 ): + self.__setPx(P26=1, P27=1, P33=1, P36=1, P37=1) + self.__runCommandSync(3) + elif(lb == 2 ): + self.__setPx(P26=1, P27=1, P33=1, P36=0, P37=0) + self.__runCommandSync(3) + elif(lb == 3 ): + self.__setPx(P26=1, P27=0, P33=1, P36=1, P37=0) + self.__runCommandSync(3) + self.top.flushCommands() + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setPx() + self.__loadCommand(6) # VPP off + + def __verifyErase(self): + ok = 0 + image = self.readProgmem() + for addr in range(0, self.flashPageSize*self.flashPages): + if byte2int(image[addr]) != 0xFF: + ok = 1 + return ok + + def __verifyProgmem(self,image): + data = self.readProgmem() + ok = 0 + for addr in range(0, len(image)-1): + if byte2int(image[addr]) != byte2int(data[addr]): + ok = 1 + return ok + + def __loadData(self, data): + self.top.cmdFPGAWrite(0x10, data) + + def __loadAddress(self, addr): + self.top.cmdFPGAWrite(0x11, addr & 0x00FF) + self.top.cmdFPGAWrite(0x12, (addr >> 8) & 0x3FFF) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x13, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setPx(self, P26=0, P27=0, P33=0, P36=0, P37=0, nPSEN=0, RST=1): + data = 0 + if P26: + data |= 1 + if P27: + data |= 2 + if P33: + data |= 4 + if P36: + data |= 8 + if P37: + data |= 16 + if nPSEN: + data |= 32 + if RST: + data |= 64 + self.top.cmdFPGAWrite(0x16, data) + + def __getStatusFlags(self): + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + return byte2int(stat[0]) + + def __busy(self): + return bool(self.__getStatusFlags() & self.STAT_BUSY) + + def __busyWait(self): + for i in range(0, 26): + if not self.__busy(): + return + self.top.hostDelay(0.001) + self.throwError("Timeout in busywait.") + + def __progWait(self): + for i in range(0,4): + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + if (byte2int(stat[0]) & self.STAT_BUSY) == 0: + return byte2int(stat[0]) + self.top.hostDelay(0.001) + self.throwError("Timeout in busywait.") +lockbitDesc = ( + BitDescription(0, "Unused"), + BitDescription(1, "Unused"), + BitDescription(2, "BLB01 - further programming of flash mem. is disabled"), + BitDescription(3, "BLB02 - verify disabled"), + BitDescription(4, "BLB03 - external execution disabled"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), +) +ChipDescription( + Chip_AT89S52dip40, + bitfile = "at89s5xdip40", + chipID = "at89s52dip40", + runtimeID = (0x0005, 0x01), + chipVendors = "Atmel", + description = "AT89S52", + lockbitDesc = lockbitDesc, + maintainer = None, + packages = ( ("DIP40", ""), ) +) diff --git a/libtoprammer/chips/microchip01/__init__.py b/libtoprammer/chips/microchip01/__init__.py new file mode 100644 index 0000000..bc1cdbd --- /dev/null +++ b/libtoprammer/chips/microchip01/__init__.py @@ -0,0 +1,6 @@ +# Import all chip modules in **ALPHABETICAL** order + +from pic10f200dip8 import * +from pic10f202dip8 import * +from pic12f508dip8 import * +from pic16f59sip6 import * diff --git a/libtoprammer/chips/microchip01/microchip01_common.py b/libtoprammer/chips/microchip01/microchip01_common.py new file mode 100644 index 0000000..b121392 --- /dev/null +++ b/libtoprammer/chips/microchip01/microchip01_common.py @@ -0,0 +1,425 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip common +# +# Copyright (c) 2012 Pavel Stemberk +# +# 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 * + +class Chip_Microchip01_common(Chip): + CMD_LOAD_DATA_FOR_PGM = 0x02 + CMD_READ_DATA_FROM_PGM = 0x04 + CMD_INCREMENT_ADDRESS = 0x06 + CMD_BEGIN_PROGRAMMING = 0x08 + CMD_END_PROGRAMMING = 0x0E + CMD_BULK_ERASE_PGM = 0x09 + + PROGCMD_SENDINSTR = 1 + PROGCMD_SENDDATA = 2 + PROGCMD_READDATA = 3 + + STAT_BUSY= 0x01 + STAT_SDIO = 0x02 + + def __init__(self, + chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, + signature, + flashPageSize, flashPages, + eepromPageSize, eepromPages, + fuseBytes + ): + Chip.__init__(self, + chipPackage = chipPackage, + chipPinVCC = chipPinVCC, + chipPinsVPP = chipPinsVPP, + chipPinGND = chipPinGND) + self.signature = signature + self.flashPageSize = flashPageSize # Flash page size, in words + self.flashPages = flashPages # Nr of flash pages + self.eepromPageSize = eepromPageSize # EEPROM page size, in bytes + self.eepromPages = eepromPages # Nr of EEPROM pages + self.fuseBytes = fuseBytes # Nr of fuse bytes + self.PC=0 + self.isInPmMode=False + + + def readSignature(self): + self.progressMeterInit("Reading signature", 0) + signature = self.__readSignature() + self.progressMeterFinish() + return signature + + def erase(self): + if(hasattr(self,'osccalAddr')): + self.__erase() + else: + self.__erase(keepOSCCAL=False) + + def __erase(self, keepConfigWord=False, keepOSCCAL=True, keepUserIDLocation=False): + OSCCAL = 0xfff + self.__enterPM() + if(keepConfigWord): + self.progressMeterInit("Reading ConfigWord for backup", 0) + CW = self.__getConfigWord() + self.progressMeterFinish() + if(keepOSCCAL): + self.progressMeterInit("Reading OSCCAL)", 0) + self.__setPC(self.osccalAddr) + self.__sendReadFlashInstr() + self.top.cmdDelay(0.00005) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + OSCCAL=self.top.cmdReadBufferReg16() + self.progressMeterFinish() + if(OSCCAL == 0xfff): + self.progressMeterInit("OSCCAL value lost, restoring from backup location ...", 0) + self.__setPC(self.osccalBackupAddr-self.osccalAddr) + self.__sendReadFlashInstr() + self.top.cmdDelay(0.00005) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + OSCCAL=self.top.cmdReadBufferReg16() + self.progressMeterFinish() + #print ("osccal: %x\n" % OSCCAL) + #erase User ID Location and backup osccal Tooo + if(not keepUserIDLocation): + self.__setPC(self.userIDLocationAddr) + self.progressMeterInit("Erasing chip", 0) + self.__sendInstr(self.CMD_BULK_ERASE_PGM) + self.top.hostDelay(0.01) #Tera + self.progressMeterFinish() + #OSCCAL=0xC12 + if(keepOSCCAL and OSCCAL != 0xfff): + self.__enterPM() + self.progressMeterInit("Writing osccal, value %x" % OSCCAL, 0) + self.__setPC(self.osccalAddr) + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + self.__setSDI(OSCCAL) + self.top.hostDelay(0.000005) + self.__sendWriteFlashInstr() + self.progressMeterFinish() + if(keepConfigWord): + self.progressMeterInit("Write read ConfigWord, value %x" % CW, 0) + self.__writeConfigWord(CW) + self.progressMeterFinish() + self.__exitPM() + + + def readProgmem(self): + nrWords = self.flashPages * self.flashPageSize + image = "" + self.__enterPM() + self.progressMeterInit("Reading flash", nrWords) + bufferedBytes = 0 + for word in range(0, nrWords): + self.__incrementPC(1) + self.__sendReadFlashInstr() + #self.__busyWait() + self.top.cmdDelay(0.00002) #20us wait - inconsistent data if skipped + self.__readSDOBufferLow() + bufferedBytes += 1 + self.__readSDOBufferHigh() + bufferedBytes += 1 + if bufferedBytes == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(bufferedBytes) + self.progressMeter(word) + bufferedBytes = 0 + image += self.top.cmdReadBufferReg(bufferedBytes) + self.progressMeterFinish() + self.__exitPM() + return image + + def writeProgmem(self, image): + self.__enterPM() + nrWords = self.flashPages * self.flashPageSize + if len(image) > nrWords * 2 or len(image) % 2 != 0: + self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\ + (len(image), nrWords * 2)) + self.__enterPM() + self.progressMeterInit("Writing flash", len(image) // 2) + for word in range(0, len(image) // 2): + self.progressMeter(word) + #do not swap following two lines + self.__incrementPC(1) + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + WD = (byte2int(image[word * 2 + 1])<<8) | byte2int(image[word * 2 + 0]) + if(WD != 0xfff): + self.__setSDI(WD) + self.top.hostDelay(0.00002) + self.__sendWriteFlashInstr() + + self.progressMeterFinish() + self.__exitPM() + + def readFuse(self): + self.__enterPM() + fuses = [] + self.progressMeterInit("Reading fuses (configuration word)", 0) + for CW in self.__getConfigWord(): + fuses.append(int2byte(CW & 0x00ff)) + fuses.append(int2byte((CW >> 8) & 0x00ff)) + self.progressMeterFinish() + self.__exitPM() + return b"".join(fuses) + + def readUserIdLocation(self): + self.__enterPM() + self.__setPC(self.userIDLocationAddr) + for i in range(0, self.userIDLocationSize): + self.__incrementPC(1) + self.__sendReadFlashInstr() + self.top.hostDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + self.__exitPM() + return self.top.cmdReadBufferReg()[0:2*self.userIDLocationSize-1] + + def writeUserIdLocation(self, image): + if len(image) > self.userIDLocationSize * 2 or len(image) % 2 != 0: + self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\ + (len(image), self.userIDLocationSize * 2)) + self.__enterPM() + self.__setPC(self.userIDLocationAddr) + self.progressMeterInit("Writing User ID Location", len(image) // 2) + for word in range(0, len(image) // 2): + self.progressMeter(word) + #do not swap following two lines + self.__incrementPC(1) + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + WD = (byte2int(image[word * 2 + 1])<<8) | byte2int(image[word * 2 + 0]) + if(WD != 0xfff): + self.__setSDI(WD) + self.top.hostDelay(0.00002) + self.__sendWriteFlashInstr() + self.progressMeterFinish() + self.__exitPM() + + def __getConfigWordSize(self): + return self.fuseBytes // 2 + + def __getConfigWord(self): + self.__enterPM() + self.__setPC(self.configWordAddr) + retVal=[] + for i in range(0,self.__getConfigWordSize()): + self.__sendReadFlashInstr() + self.top.cmdDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + retVal.append(self.top.cmdReadBufferReg16()) + self.__incrementPC(1) + return retVal + + def writeFuse(self, image): + self.__enterPM() + if len(image) != 2*self.__getConfigWordSize(): + self.throwError("Invalid Fuses image size %d (expected %d)" %\ + (len(image), 2*self.__getConfigWordSize())) + self.progressMeterInit("Writing fuses", 0) + #print "image1:%x,,%x,,%x" % (byte2int(image[0]),byte2int(image[1]),byte2int(image[1])<<8) + CW=[] + for tBytes in zip(image[::2],image[1::2]): + CW.append((byte2int(image[1])<<8) | byte2int(image[0])) + self.__writeConfigWord(CW) + self.progressMeterFinish() + self.__exitPM() + + def __writeConfigWord(self, listConfigWord16): + self.__enterPM() + self.__setPC(self.configWordAddr) + for configWord16 in listConfigWord16: + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + self.__setSDI(configWord16) + self.top.hostDelay(0.00002) + self.__sendWriteFlashInstr() + self.__incrementPC(1) + + def __readSignature(self): + if(hasattr(self,'deviceIDAddr')): + idAddr = self.deviceIDAddr + idSize = 1 + else: + idAddr = self.userIDLocationAddr + idSize = self.userIDLocationSize + self.__enterPM() + self.__incrementPC(idAddr) + for i in range(0, idSize): + self.__incrementPC(1) + self.__sendReadFlashInstr() + self.top.hostDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + self.__exitPM() + return self.top.cmdReadBufferReg()[0:2*idSize-1] + + def __enterPM(self): + if self.isInPmMode: + self.__setPC(self.logicalFlashSize - 1) + return + self.PC = self.logicalFlashSize - 1 + "Enter HV programming mode. Vdd first entry mode" + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(False) + self.__setPins(0,0) + self.top.cmdSetVCCVoltage(self.voltageVDD) + self.top.cmdSetVPPVoltage(self.voltageVPP) + #self.top.cmdEnableZifPullups(True) + self.applyGND(True) + + self.applyVCC(True) + self.top.cmdDelay(0.000005) + + for i in range(0,2): + self.applyVPP(True) + self.top.cmdDelay(0.000005) + self.applyVPP(False) + self.top.cmdDelay(0.000031) + self.applyVPP(True) + #self.top.cmdEnableZifPullups(True) + + self.top.cmdDelay(0.000005) #least 5us is required to reach Vdd first entry PM + self.isInPmMode=True + + def __checkSignature(self): + signature = self.__readSignature() + if signature != self.signature: + msg = "Unexpected device signature. " +\ + "Want %02X%02X%02X, but got %02X%02X%02X" % \ + (byte2int(self.signature[0]), byte2int(self.signature[1]), + byte2int(self.signature[2]), + byte2int(signature[0]), byte2int(signature[1]), + byte2int(signature[2])) + if self.top.getForceLevel() >= 1: + self.printWarning(msg) + else: + self.throwError(msg) + + def __exitPM(self): + "Exit HV programming mode. Vdd last exit mode" + self.__setPins(0,0) + self.applyVPP(False) + self.applyGND(False) + self.top.hostDelay(0.000005) + self.applyVCC(False) + self.isInPmMode=False + + def __sendReadFlashInstr(self): + ''' + ''' + self.__sendInstr(self.CMD_READ_DATA_FROM_PGM) + self.__loadCommand(self.PROGCMD_READDATA) + + def __sendWriteFlashInstr(self): + ''' + ''' + self.__loadCommand(self.PROGCMD_SENDDATA) + self.top.hostDelay(0.000005) + self.__sendInstr(self.CMD_BEGIN_PROGRAMMING) + self.top.hostDelay(0.001)#025) #Tprog + self.__sendInstr(self.CMD_END_PROGRAMMING) + self.top.hostDelay(0.0001) #Tdis + + def __sendInstr(self, SDI): + ''' + see __loadCommand for availabla commands + ''' + self.top.cmdFPGAWrite(0x13, SDI & 0xFF) + self.__loadCommand(self.PROGCMD_SENDINSTR) + # We do not poll the busy flag, because that would result + # in a significant slowdown. We delay long enough for the + # command to finish execution, instead. + #self.top.hostDelay(0.001) + self.top.hostDelay(0.000005) + + def __setSDI(self, sdi): + ''' + set 14 bit sdi value + ''' + self.top.cmdFPGAWrite(0x13, sdi & 0xFF) + self.top.cmdFPGAWrite(0x14, (sdi>>8) & 0x0F) + + def __loadCommand(self, command): + ''' + `define CMD_SENDINSTR 1 + `define CMD_SENDDATA 2 + `define CMD_READDATA 3 + ''' + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setPC(self, address): + while(self.PC!=address): + self.__incrementPC(1) + + def __incrementPC(self, count): + for address in range(0, count): + self.__sendInstr(self.CMD_INCREMENT_ADDRESS) + self.PC += 1 + if (self.PC == self.logicalFlashSize): + self.PC = 0 + + def __setPins(self, ICSPCLK=0, SDIODRIVEN=0, SDIOVALUE=0): + ''' + setPins + ''' + data = 0 + if ICSPCLK: + data |= 1 + if SDIODRIVEN: + data |= 2 + if SDIOVALUE: + data |= 4 + self.top.cmdFPGAWrite(0x15, data) + + def __getStatusFlags(self): + ''' + ''' + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + return byte2int(stat[0]) + + def __readSDOBufferHigh(self): + self.top.cmdFPGARead(0x10) + + def __readSDOBufferLow(self): + self.top.cmdFPGARead(0x13) + + def __rawSDIOState(self): + return bool(self.__getStatusFlags() & self.STAT_SDIO) + + def __busy(self): + return bool(self.__getStatusFlags() & self.STAT_BUSY) + + def __busyWait(self): + for i in range(0, 100): + if not self.__busy(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout in busywait.") + + def __waitHighSDIO(self): + for i in range(0, 100): + if self.__rawSDOState(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout waiting for SDO.") diff --git a/libtoprammer/chips/microchip01/pic10f200dip8.py b/libtoprammer/chips/microchip01/pic10f200dip8.py new file mode 100644 index 0000000..855f7a1 --- /dev/null +++ b/libtoprammer/chips/microchip01/pic10f200dip8.py @@ -0,0 +1,83 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC10F200, PIC10F204 and PI10f220 DIP8 +# +# Copyright (c) 2012 Pavel Stemberk +# +# 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 microchip01_common import * + + +class Chip_Pic10F200dip8(Chip_Microchip01_common): + voltageVDD = 5 + voltageVPP =13 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashSize = 0x200 + userIDLocationSize = 4 + SUPPORT_SIGREAD = (0 << 1) + + + def __init__(self): + Chip_Microchip01_common.__init__(self, + chipPackage = "DIP8", + chipPinVCC = 2, + chipPinsVPP = 8, + chipPinGND = 7, + signature = "\x09\x18\x24\x35", + flashPageSize = 0x100, + flashPages = 1, + eepromPageSize = 0, + eepromPages = 0, + fuseBytes = 2 + ) + self.configWordAddr = self.logicalFlashSize-1 + self.osccalAddr = self.flashPageSize-1 + self.userIDLocationAddr = self.flashPageSize + self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+1), (2*0xFFF, 2*0xFFF+1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + +fuseDesc = ( + BitDescription(0, "Unused"), + BitDescription(1, "Unused"), + BitDescription(2, "WDTE"), + BitDescription(3, "!CP"), + BitDescription(4, "MCLRE"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), + BitDescription(9, "Unused"), + BitDescription(10, "Unused"), + BitDescription(11, "Unused"), +) + +ChipDescription( + Chip_Pic10F200dip8, + bitfile = "pic10fxxxdip8", + chipID = "pic10f200dip8", + runtimeID = (0xDE01, 0x01), + chipVendors = "Microchip", + description = "PIC10F200, PIC10F204, PIC10F220", + packages = ( ("DIP8", ""), ), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip01/pic10f202dip8.py b/libtoprammer/chips/microchip01/pic10f202dip8.py new file mode 100644 index 0000000..5c835bb --- /dev/null +++ b/libtoprammer/chips/microchip01/pic10f202dip8.py @@ -0,0 +1,81 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC10F202, PIC10F206 and PIC10f222 DIP8 +# +# Copyright (c) 2012 Pavel Stemberk +# +# 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 microchip01_common import * + +class Chip_Pic10F202dip8(Chip_Microchip01_common): + voltageVDD = 5 + voltageVPP = 13 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashSize = 0x400 + userIDLocationSize = 4 + SUPPORT_SIGREAD = (0 << 1) + + def __init__(self): + Chip_Microchip01_common.__init__(self, + chipPackage="DIP8", + chipPinVCC=2, + chipPinsVPP=8, + chipPinGND=7, + signature="\x09\x18\x24\x35", + flashPageSize=0x200, + flashPages=1, + eepromPageSize=0, + eepromPages=0, + fuseBytes=2 + ) + self.configWordAddr = self.logicalFlashSize - 1 + self.osccalAddr = self.flashPageSize - 1 + self.userIDLocationAddr = self.flashPageSize + self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+1), (2*0xFFF, 2*0xFFF+1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + +fuseDesc = ( + BitDescription(0, "Unused"), + BitDescription(1, "Unused"), + BitDescription(2, "WDTE"), + BitDescription(3, "!CP"), + BitDescription(4, "MCLRE"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), + BitDescription(9, "Unused"), + BitDescription(10, "Unused"), + BitDescription(11, "Unused"), +) + +ChipDescription( + Chip_Pic10F202dip8, + bitfile = "pic10fxxxdip8", + chipID = "pic10f202dip8", + runtimeID = (0xDE01, 0x01), + chipVendors = "Microchip", + description = "PIC10F202, PIC10F206, PIC10F222", + packages = (("DIP8", ""),), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip01/pic12f508dip8.py b/libtoprammer/chips/microchip01/pic12f508dip8.py new file mode 100644 index 0000000..63024fa --- /dev/null +++ b/libtoprammer/chips/microchip01/pic12f508dip8.py @@ -0,0 +1,75 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC12F508 DIP8 +# +# Copyright (c) 2013 Pavel Stemberk +# +# 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 microchip01_common import * + +class Chip_Pic12F508dip8(Chip_Microchip01_common): + voltageVDD = 5 + voltageVPP = 13 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashSize = 0x400 + userIDLocationSize = 4 + SUPPORT_SIGREAD = (0 << 1) + + def __init__(self): + Chip_Microchip01_common.__init__(self, + chipPackage="DIP8", + chipPinVCC=1, + chipPinsVPP=4, + chipPinGND=8, + signature="", + flashPageSize=0x200, + flashPages=1, + eepromPageSize=0, + eepromPages=0, + fuseBytes=2 + ) + self.configWordAddr = self.logicalFlashSize - 1 + self.osccalAddr = self.flashPageSize - 1 + self.userIDLocationAddr = self.flashPageSize + self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize +fuseDesc = ( + BitDescription(0, "FOSC[0] 00=LP, 01=XT, 10=INTOSC, 11=EXTRC"), + BitDescription(1, "FOSC[1]"), + BitDescription(2, "WDTE"), + BitDescription(3, "!CP"), + BitDescription(4, "MCLRE"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), + BitDescription(9, "Unused"), + BitDescription(10, "Unused"), + BitDescription(11, "Unused"), +) +ChipDescription( + Chip_Pic12F508dip8, + bitfile = "microchip01dip8", + chipID = "pic12f508dip8", + runtimeID = (0xDE02, 0x01), + chipVendors = "Microchip", + description = "PIC12F508", + fuseDesc = fuseDesc, + packages = (("DIP8", ""),), + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip01/pic16f59sip6.py b/libtoprammer/chips/microchip01/pic16f59sip6.py new file mode 100644 index 0000000..e6c9287 --- /dev/null +++ b/libtoprammer/chips/microchip01/pic16f59sip6.py @@ -0,0 +1,81 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC16F59 SIP6 +# +# Copyright (c) 2013 Pavel Stemberk +# +# 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 microchip01_common import * + + +class Chip_Pic16F59sip6(Chip_Microchip01_common): + voltageVDD = 5 + voltageVPP =13 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashSize = 0x1000 + userIDLocationSize = 4 + SUPPORT_SIGREAD = (0 << 1) + + + def __init__(self): + Chip_Microchip01_common.__init__(self, + chipPackage = "DIP10", + chipPinVCC = 9, + chipPinsVPP = 10, + chipPinGND = 8, + signature = "", + flashPageSize = 0x200, + flashPages = 4, + eepromPageSize = 0, + eepromPages = 0, + fuseBytes = 2 + ) + self.configWordAddr = self.logicalFlashSize-1 + self.userIDLocationAddr = self.flashPageSize + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+self.fuseBytes-1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + +fuseDesc = ( + BitDescription(0, "FOSC0"), + BitDescription(1, "FOSC1 - 00=LP, 01=XT, 10=HS, 11=RC"), + BitDescription(2, "WDTE"), + BitDescription(3, "!CP"), + BitDescription(4, "Unused"), + BitDescription(5, "Unused"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), + BitDescription(9, "Unused"), + BitDescription(10, "Unused"), + BitDescription(11, "Unused"), +) + +ChipDescription( + Chip_Pic16F59sip6, + bitfile = "microchip01sip6", + chipID = "pic16f59sip6", + runtimeID = (0xDE05, 0x01), + chipVendors = "Microchip", + description = "PIC16F59", + packages = ( ("DIP10", ""), ), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip02/__init__.py b/libtoprammer/chips/microchip02/__init__.py new file mode 100644 index 0000000..fd04f4e --- /dev/null +++ b/libtoprammer/chips/microchip02/__init__.py @@ -0,0 +1,5 @@ +# Import all chip modules in **ALPHABETICAL** order + +from pic10f322dip8 import * +from pic12f1822dip8 import * +from pic16f1824dip14 import * diff --git a/libtoprammer/chips/microchip02/microchip02_common.py b/libtoprammer/chips/microchip02/microchip02_common.py new file mode 100644 index 0000000..b31874d --- /dev/null +++ b/libtoprammer/chips/microchip02/microchip02_common.py @@ -0,0 +1,449 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip common +# +# Copyright (c) 2012 Pavel Stemberk +# +# 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 * + +class Chip_Microchip02_common(Chip): + CMD_LOAD_CONFIGURATION = 0x00 + CMD_LOAD_DATA_FOR_PGM = 0x02 + CMD_READ_DATA_FROM_PGM = 0x04 + CMD_INCREMENT_ADDRESS = 0x06 + CMD_RESET_ADDRESS = 0x16 + CMD_BEGIN_INTERNALLY_TIMED_PROGRAMMING = 0x08 + CMD_BEGIN_EXTERNALLY_TIMED_PROGRAMMING = 0x18 + CMD_END_EXTERNALLY_TIMED_PROGRAMMING = 0x0A + CMD_BULK_ERASE_PGM = 0x09 + CMD_ROW_ERASE_PGM = 0x11 + + PROGCMD_SENDINSTR = 1 + PROGCMD_SENDDATA = 2 + PROGCMD_READDATA = 3 + + STAT_BUSY= 0x01 + STAT_SDIO = 0x02 + + def __init__(self, + chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, + signature, + flashPageSize, flashPages, + eepromPageSize, eepromPages, + fuseBytes + ): + Chip.__init__(self, + chipPackage = chipPackage, + chipPinVCC = chipPinVCC, + chipPinsVPP = chipPinsVPP, + chipPinGND = chipPinGND) + self.signature = signature + self.flashPageSize = flashPageSize # Flash page size, in words + self.flashPages = flashPages # Nr of flash pages + self.eepromPageSize = eepromPageSize # EEPROM page size, in bytes + self.eepromPages = eepromPages # Nr of EEPROM pages + self.fuseBytes = fuseBytes # Nr of fuse bytes + self.PC=0 + self.isInPmMode = False + self.isInsideProgramMemoryArea = True + #self.rowSize = rowSize + #self.nLatches = nLatches + #self.logicalFlashProgramMemorySize = logicalFlashProgramMemorySize + #self.logicalFlashConfigurationMemorySize = logicalFlashConfigurationMemorySize + + + def readSignature(self): + self.progressMeterInit("Reading signature", 0) + signature = self.__readSignature() + self.progressMeterFinish() + return signature + + def erase(self): + self.__erase() + + def __erase(self, keepConfigWord=False, keepUserIDLocation=False): + OSCCAL = 0xfff + self.__enterPM() + if(keepConfigWord): + self.progressMeterInit("Reading ConfigWord for backup", 0) + CW = self.__getConfigWord() + self.progressMeterFinish() + #erase User ID Location and backup osccal Tooo + if(not keepUserIDLocation): + self.__enterConfigArea() + self.__setPC(self.userIDLocationAddr) + self.progressMeterInit("Erasing chip", 0) + self.__sendInstr(self.CMD_BULK_ERASE_PGM) + self.top.hostDelay(0.01) #Tera + self.progressMeterFinish() + if(keepConfigWord): + self.progressMeterInit("Write ConfigWord, value %x" % CW, 0) + self.__writeConfigWord(CW) + self.progressMeterFinish() + self.__exitPM() + + + def readProgmem(self): + nrWords = self.flashPages * self.flashPageSize + image = "" + self.__enterPM() + self.progressMeterInit("Reading flash", nrWords) + bufferedBytes = 0 + for word in range(0, nrWords): + self.__incrementPC(1) + self.__sendReadFlashInstr() + #self.__busyWait() + self.top.cmdDelay(0.00002) #20us wait - inconsistent data if skipped + self.__readSDOBufferLow() + bufferedBytes += 1 + self.__readSDOBufferHigh() + bufferedBytes += 1 + if bufferedBytes == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(bufferedBytes) + self.progressMeter(word) + bufferedBytes = 0 + image += self.top.cmdReadBufferReg(bufferedBytes) + self.progressMeterFinish() + self.__exitPM() + return image + + def writeProgmem(self, image): + self.__enterPM() + nrWords = self.flashPages * self.flashPageSize + if len(image) > nrWords * 2 or len(image) % 2 != 0: + self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\ + (len(image), nrWords * 2)) + self.__enterPM() + self.progressMeterInit("Writing flash", len(image) // 2) + for wordAddr in range(0, len(image) // 2): + self.progressMeter(wordAddr) + #do not swap following two lines + self.__incrementPC(1) + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + WD = (byte2int(image[wordAddr * 2 + 1])<<8) | byte2int(image[wordAddr * 2 + 0]) + if(WD != 0xfff): + self.__setSDI(WD) + self.top.hostDelay(0.00002) + self.__loadCommand(self.PROGCMD_SENDDATA) + self.top.hostDelay(0.000005) + self.__sendWriteFlashInstr() + + self.progressMeterFinish() + self.__exitPM() + + def readFuse(self): + self.__enterPM() + fuses = [] + self.progressMeterInit("Reading fuses (configuration word)", 0) + for CW in self.__getConfigWord(): + fuses.append(int2byte(CW & 0x00ff)) + fuses.append(int2byte((CW >> 8) & 0x00ff)) + self.progressMeterFinish() + self.__exitPM() + return b"".join(fuses) + + def readUserIdLocation(self): + self.__enterPM() + self.__enterConfigArea() + self.__setPC(self.userIDLocationAddr) + self.progressMeterInit("Reading User ID Location", 0) + for i in range(0, self.userIDLocationSize): + self.__sendReadFlashInstr() + self.top.hostDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + self.__incrementPC(1) + self.__exitPM() + self.progressMeterFinish() + return self.top.cmdReadBufferReg()[0:2*self.userIDLocationSize] + + def writeUserIdLocation(self, image): + if len(image) > self.userIDLocationSize * 2 or len(image) % 2 != 0: + self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\ + (len(image), self.userIDLocationSize * 2)) + self.__enterPM() + self.__enterConfigArea() + #self.__setPC(self.userIDLocationAddr) + self.__setPC(0x2004) + self.progressMeterInit("Writing User ID Location", (len(image) // 2) - 1) + for word in range(0, (len(image) // 2)): + self.progressMeter(word) + #do not swap following two lines + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + WD = (byte2int(image[word * 2 + 1])<<8) | byte2int(image[word * 2 + 0]) + self.__setSDI(WD) + #self.top.hostDelay(0.00002) + self.__loadCommand(self.PROGCMD_SENDDATA) + self.__incrementPC(1) + self.top.hostDelay(0.000005) + self.__sendWriteFlashInstr() + self.progressMeterFinish() + self.__exitPM() + + def __getConfigWordSize(self): + return self.fuseBytes // 2 + + def __getConfigWord(self): + self.__enterPM() + self.__enterConfigArea() + self.__setPC(self.configWordAddr) + retVal=[] + for i in range(0,self.__getConfigWordSize()): + self.__sendReadFlashInstr() + self.top.cmdDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + self.__incrementPC(1) + retVal.append(self.top.cmdReadBufferReg16()) + + return retVal + + def writeFuse(self, image): + self.__enterPM() + if len(image) != 2*self.__getConfigWordSize(): + self.throwError("Invalid Fuses image size %d (expected %d)" %\ + (len(image), 2*self.__getConfigWordSize())) + self.progressMeterInit("Writing fuses", 0) + #print "image1:%x,,%x,,%x" % (byte2int(image[0]),byte2int(image[1]),byte2int(image[1])<<8) + CW=[] + for tBytes in zip(image[::2],image[1::2]): + CW.append((byte2int(tBytes[1])<<8) | byte2int(tBytes[0])) + self.__writeConfigWord(CW) + self.progressMeterFinish() + self.__exitPM() + + def __writeConfigWord(self, listConfigWord16): + #Externally timed writes are not supported + #for Configuration and Calibration bits. Any + #externally timed write to the Configuration + #or Calibration Word will have no effect on + #the targeted word. + self.__enterPM() + self.__enterConfigArea() + self.__setPC(self.configWordAddr-1) + print "PC:{:x}".format(self.PC) + for configWord16 in listConfigWord16: + self.__incrementPC(1) + print "write CW {:x}".format(configWord16) + self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) + self.__setSDI(configWord16) + self.top.hostDelay(0.00002) + self.__loadCommand(self.PROGCMD_SENDDATA) + self.top.hostDelay(0.000005) + self.__sendInstr(self.CMD_BEGIN_INTERNALLY_TIMED_PROGRAMMING) + self.top.hostDelay(0.005)#TPINT + + + def __readSignature(self): + self.__enterPM() + self.__enterConfigArea() + self.__setPC(self.deviceIDAddr) + idSize = 1 + for i in range(0, idSize): + self.__sendReadFlashInstr() + self.top.hostDelay(0.00002) + self.__readSDOBufferLow() + self.__readSDOBufferHigh() + self.__incrementPC(1) + self.__exitPM() + return self.top.cmdReadBufferReg()[0:2*idSize] + + def __enterPM(self): + if self.isInPmMode: + self.__resetPC() + return + self.PC = 0 + "Enter HV programming mode. Vdd first entry mode" + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(False) + self.__setPins(0,0) + self.top.cmdSetVCCVoltage(self.voltageVDD) + self.top.cmdSetVPPVoltage(self.voltageVPP) + #self.top.cmdEnableZifPullups(True) + self.applyGND(True) + + self.applyVCC(True) + self.top.cmdDelay(0.000005) + + for i in range(0,2): + self.applyVPP(True) + self.top.cmdDelay(0.000005) + self.applyVPP(False) + self.top.cmdDelay(0.000031) + self.applyVPP(True) + #self.top.cmdEnableZifPullups(True) + + self.top.cmdDelay(0.000005) #least 5us is required to reach Vdd first entry PM + self.isInPmMode=True + + def __checkSignature(self): + signature = self.__readSignature() + if signature != self.signature: + msg = "Unexpected device signature. " +\ + "Want %02X%02X%02X, but got %02X%02X%02X" % \ + (byte2int(self.signature[0]), byte2int(self.signature[1]), + byte2int(self.signature[2]), + byte2int(signature[0]), byte2int(signature[1]), + byte2int(signature[2])) + if self.top.getForceLevel() >= 1: + self.printWarning(msg) + else: + self.throwError(msg) + + def __exitPM(self): + "Exit HV programming mode. Vdd last exit mode" + self.__setPins(0,0) + self.applyVPP(False) + self.applyGND(False) + self.top.hostDelay(0.000005) + self.applyVCC(False) + self.isInPmMode=False + + def __sendReadFlashInstr(self): + ''' + ''' + self.__sendInstr(self.CMD_READ_DATA_FROM_PGM) + self.__loadCommand(self.PROGCMD_READDATA) + + def __sendWriteFlashInstr(self): + ''' + ''' + self.__sendInstr(self.CMD_BEGIN_EXTERNALLY_TIMED_PROGRAMMING) + self.top.hostDelay(0.001)#025) #Tprog + self.__sendInstr(self.CMD_END_EXTERNALLY_TIMED_PROGRAMMING) + self.top.hostDelay(0.0001) #Tdis + + def __sendInstr(self, SDI): + ''' + see __loadCommand for availabla commands + ''' + self.top.cmdFPGAWrite(0x13, SDI & 0xFF) + self.__loadCommand(self.PROGCMD_SENDINSTR) + # We do not poll the busy flag, because that would result + # in a significant slowdown. We delay long enough for the + # command to finish execution, instead. + #self.top.hostDelay(0.001) + self.top.hostDelay(0.000005) + + def __setSDI(self, sdi): + ''' + set 14 bit sdi value + ''' + self.top.cmdFPGAWrite(0x13, sdi & 0xFF) + self.top.cmdFPGAWrite(0x14, (sdi>>8) & 0x3F) + + def __loadCommand(self, command): + ''' + `define CMD_SENDINSTR 1 + `define CMD_SENDDATA 2 + `define CMD_READDATA 3 + ''' + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setPC(self, address): + if(self.isInsideProgramMemoryArea): + if(address >= self.logicalFlashProgramMemorySize): + raise(TOPException('Cannot set PC to address {:x}'.format(address))) + if(address < self.PC): + self.__resetPC() + self.__setPC(address) + else: + if(address < self.logicalFlashProgramMemorySize): + raise(TOPException('Cannot set PC to address {:x}'.format(address))) + if(address < self.PC): + self.__resetPC() + self.__enterConfigArea() + self.__setPC(address) + while(self.PC!=address): + self.__incrementPC(1) + + def __incrementPC(self, count): + for address in range(0, count): + self.__sendInstr(self.CMD_INCREMENT_ADDRESS) + self.PC += 1 + if(self.isInsideProgramMemoryArea): + if (self.PC == self.logicalFlashProgramMemorySize): + self.PC = 0 + else: + if (self.PC == self.logicalFlashConfigurationMemorySize): + self.PC = self.logicalFlashProgramMemorySize + + def __resetPC(self): + self.__sendInstr(self.CMD_RESET_ADDRESS) + self.PC = 0 + self.isInsideProgramMemoryArea = True + + def __enterConfigArea(self, wordLatched = 0): + self.__sendInstr(self.CMD_LOAD_CONFIGURATION) + self.__setSDI(wordLatched) + #self.top.hostDelay(0.00002) + self.__loadCommand(self.PROGCMD_SENDDATA) + self.PC = self.logicalFlashProgramMemorySize + self.isInsideProgramMemoryArea = False + + def __setPins(self, ICSPCLK=0, SDIODRIVEN=0, SDIOVALUE=0): + ''' + setPins + ''' + data = 0 + if ICSPCLK: + data |= 1 + if SDIODRIVEN: + data |= 2 + if SDIOVALUE: + data |= 4 + self.top.cmdFPGAWrite(0x15, data) + + def __getStatusFlags(self): + ''' + ''' + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + return byte2int(stat[0]) + + def __readSDOBufferHigh(self): + self.top.cmdFPGARead(0x10) + + def __readSDOBufferLow(self): + self.top.cmdFPGARead(0x13) + + def __rawSDIOState(self): + return bool(self.__getStatusFlags() & self.STAT_SDIO) + + def __busy(self): + return bool(self.__getStatusFlags() & self.STAT_BUSY) + + def __busyWait(self): + for i in range(0, 100): + if not self.__busy(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout in busywait.") + + def __waitHighSDIO(self): + for i in range(0, 100): + if self.__rawSDOState(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout waiting for SDO.") diff --git a/libtoprammer/chips/microchip02/pic10f322dip8.py b/libtoprammer/chips/microchip02/pic10f322dip8.py new file mode 100644 index 0000000..6bf7ae6 --- /dev/null +++ b/libtoprammer/chips/microchip02/pic10f322dip8.py @@ -0,0 +1,86 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC10F322 DIP8 +# +# Copyright (c) 2013 Pavel Stemberk +# +# 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 microchip02_common import * + +class Chip_Pic10F322dip8(Chip_Microchip02_common): + voltageVDD = 3 + voltageVPP = 8.5 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashProgramMemorySize = 0x2000 + logicalFlashConfigurationMemorySize = 0x2000 + userIDLocationSize = 4 + rowSize = 32 + nLatches = 16 + + def __init__(self): + Chip_Microchip02_common.__init__(self, + chipPackage="DIP8", + chipPinVCC=2, + chipPinsVPP=8, + chipPinGND=7, + signature="\x02\x84", + flashPageSize=0x200, + flashPages=1, + eepromPageSize=0, + eepromPages=0, + fuseBytes=2 + ) + self.configWordAddr = 0x2007 + #self.osccalAddr = 0x2000 + self.userIDLocationAddr = 0x2000 + self.deviceIDAddr = 0x2006 + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + #self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + +fuseDesc = ( + BitDescription(0, "FOSC, 1=CLKIN, 0=internal"), + BitDescription(1, "BOREN[0]"), + BitDescription(2, "BOREN[1]"), + BitDescription(3, "WDTE[0]"), + BitDescription(4, "WDTE[1]"), + BitDescription(5, "nPWRTE"), + BitDescription(6, "MCLRE, 1=RA3 is nMCLR, weak pull-up enabled"), + BitDescription(7, "nCP"), + BitDescription(8, "LVP"), + BitDescription(9, "LPBOREN"), + BitDescription(10, "BORV"), + BitDescription(11, "WRT[0]"), + BitDescription(12, "WRT[1] 11=write protection off"), + BitDescription(13, "Unused"), +) + +ChipDescription( + Chip_Pic10F322dip8, + bitfile = "pic10fxxxdip8", + chipID = "pic10f322dip8", + runtimeID = (0xDE01, 0x01), + chipVendors = "Microchip", + description = "PIC10F322, PIC10LF322", + packages = (("DIP8", ""),), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip02/pic12f1822dip8.py b/libtoprammer/chips/microchip02/pic12f1822dip8.py new file mode 100644 index 0000000..cf69d32 --- /dev/null +++ b/libtoprammer/chips/microchip02/pic12f1822dip8.py @@ -0,0 +1,103 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC12F1822 DIP8 +# +# Copyright (c) 2012 Pavel Stemberk +# +# 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 microchip02_common import * + +class Chip_Pic12F1822dip8(Chip_Microchip02_common): + voltageVDD = 3 + voltageVPP = 8.5 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashProgramMemorySize = 0x8000 + logicalFlashConfigurationMemorySize = 0x8000 + rowSize = 16 + nLatches = 16 + userIDLocationSize = 4 + + def __init__(self): + Chip_Microchip02_common.__init__(self, + chipPackage="DIP8", + chipPinVCC=1, + chipPinsVPP=4, + chipPinGND=8, + signature="\x08\x27", + flashPageSize=0x800, + flashPages=1, + eepromPageSize=0, + eepromPages=0, + fuseBytes=4 + ) + self.configWordAddr = 0x8007 + #self.osccalAddr = 0x2000 + self.userIDLocationAddr = 0x8000 + self.deviceIDAddr = 0x8006 + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+self.fuseBytes-1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + #self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + +fuseDesc = ( + BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), + BitDescription(1, "FOSC[1]"), + BitDescription(2, "FOSC[2]"), + BitDescription(3, "WDTE[0], 00=WDT disabled, 11=WDT enabled"), + BitDescription(4, "WDTE[1]"), + BitDescription(5, "nPWRTE"), + BitDescription(6, "MCLRE, 1=nMCLR/Vpp pin is nMCLR, weak pull-up enabled, ignored if LVP=1 "), + BitDescription(7, "nCP 1=program memory code protection is disabled"), + BitDescription(8, "nCPD, 1=data memory code protection is disabled"), + BitDescription(9, "BOREN[0], 00=BOR disabled"), + BitDescription(10, "BOREN[1]"), + BitDescription(11, "nCLKOUTEN, 0=CLKOUT is enabled on CLKOUT pin"), + BitDescription(12, "IESO, 0=Internal/External Switchover mode is disabled"), + BitDescription(13, "FCMEM, 0=Fail-Safe Clock Monitor is disabled"), + BitDescription(14, "NA"), + BitDescription(15, "NA"), + + BitDescription(16, "WRT[0], 11=Write protection off"), + BitDescription(17, "WRT[1]"), + BitDescription(18, "Unused"), + BitDescription(19, "Unused"), + BitDescription(20, "Unused"), + BitDescription(21, "Unused"), + BitDescription(22, "Unused"), + BitDescription(23, "Unused"), + BitDescription(24, "PLLEN, 0=4xPLL disabled"), + BitDescription(25, "STVREN, 1=Stack overflow or underflow will cause a reset"), + BitDescription(26, "BORV"), + BitDescription(27, "Unused"), + BitDescription(28, "nDEBUG, 0=ICSPCLK and ICSPDAT are dedicated to the debugger"), + BitDescription(29, "LVP 1=Low-voltage programming enabled"), +) + +ChipDescription( + Chip_Pic12F1822dip8, + bitfile = "microchip01dip8", + chipID = "pic12f1822dip8", + runtimeID = (0xDE02, 0x01), + chipVendors = "Microchip", + description = "PIC12F1822, PIC12LF1822", + packages = (("DIP8", ""),), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip02/pic16f1824dip14.py b/libtoprammer/chips/microchip02/pic16f1824dip14.py new file mode 100644 index 0000000..2acf422 --- /dev/null +++ b/libtoprammer/chips/microchip02/pic16f1824dip14.py @@ -0,0 +1,103 @@ +""" +# TOP2049 Open Source programming suite +# +# Microchip PIC16F1824 DIP14 +# +# Copyright (c) 2013 Pavel Stemberk +# +# 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 microchip02_common import * + +class Chip_Pic16F1824dip14(Chip_Microchip02_common): + voltageVDD = 3 + voltageVPP = 8.5 + #CONFIGURATION WORD FOR PIC10F200/202/204/206 + #X X X X X X X MCLRE /CP WDT X X + logicalFlashProgramMemorySize = 0x8000 + logicalFlashConfigurationMemorySize = 0x8000 + rowSize = 32 + nLatches = 32 + userIDLocationSize = 4 + + def __init__(self): + Chip_Microchip02_common.__init__(self, + chipPackage="DIP14", + chipPinVCC=1, + chipPinsVPP=4, + chipPinGND=14, + signature="\x43\x27", + flashPageSize=0x1000, + flashPages=1, + eepromPageSize=0, + eepromPages=0, + fuseBytes=4 + ) + self.configWordAddr = 0x8007 + #self.osccalAddr = 0x2000 + self.userIDLocationAddr = 0x8000 + self.deviceIDAddr = 0x8006 + self.programMemoryByteAddressRange = [(0,2*self.flashPageSize)] + self.configWordByteAddressRange = [(2*self.configWordAddr,2*self.configWordAddr+self.fuseBytes-1)] + self.userIDLocationByteAddressRange = [(2*self.userIDLocationAddr, 2*(self.userIDLocationAddr+self.userIDLocationSize)-1)] + + #self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + +fuseDesc = ( + BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), + BitDescription(1, "FOSC[1]"), + BitDescription(2, "FOSC[2]"), + BitDescription(3, "WDTE[0], 00=WDT disabled, 11=WDT enabled"), + BitDescription(4, "WDTE[1]"), + BitDescription(5, "nPWRTE"), + BitDescription(6, "MCLRE, 1=nMCLR/Vpp pin is nMCLR, weak pull-up enabled, ignored if LVP=1 "), + BitDescription(7, "nCP 1=program memory code protection is disabled"), + BitDescription(8, "nCPD, 1=data memory code protection is disabled"), + BitDescription(9, "BOREN[0], 00=BOR disabled"), + BitDescription(10, "BOREN[1]"), + BitDescription(11, "nCLKOUTEN, 0=CLKOUT is enabled on CLKOUT pin"), + BitDescription(12, "IESO, 0=Internal/External Switchover mode is disabled"), + BitDescription(13, "FCMEM, 0=Fail-Safe Clock Monitor is disabled"), + BitDescription(14, "NA"), + BitDescription(15, "NA"), + + BitDescription(16, "WRT[0], 11=Write protection off"), + BitDescription(17, "WRT[1]"), + BitDescription(18, "Unused"), + BitDescription(19, "Unused"), + BitDescription(20, "Unused"), + BitDescription(21, "Unused"), + BitDescription(22, "Unused"), + BitDescription(23, "Unused"), + BitDescription(24, "PLLEN, 0=4xPLL disabled"), + BitDescription(25, "STVREN, 1=Stack overflow or underflow will cause a reset"), + BitDescription(26, "BORV"), + BitDescription(27, "Unused"), + BitDescription(28, "nDEBUG, 0=ICSPCLK and ICSPDAT are dedicated to the debugger"), + BitDescription(29, "LVP 1=Low-voltage programming enabled"), +) + +ChipDescription( + Chip_Pic16F1824dip14, + bitfile = "microchip01dip14dip20", + chipID = "pic16f1824dip14", + runtimeID = (0xDE03, 0x01), + chipVendors = "Microchip", + description = "PIC16F1824, PIC16LF1824", + packages = (("DIP14", ""),), + fuseDesc = fuseDesc, + maintainer = "Pavel Stemberk ", +) diff --git a/libtoprammer/chips/microchip_common.py b/libtoprammer/chips/microchip_common.py deleted file mode 100644 index db05cb8..0000000 --- a/libtoprammer/chips/microchip_common.py +++ /dev/null @@ -1,353 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Microchip common -# -# Copyright (c) 2012 Pavel Stemberk -# -# 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 * - -class Chip_Microchip_common(Chip): - CMD_LOAD_DATA_FOR_PGM = 0x02 - CMD_READ_DATA_FROM_PGM = 0x04 - CMD_INCREMENT_ADDRESS = 0x06 - CMD_BEGIN_PROGRAMMING = 0x08 - CMD_END_PROGRAMMING = 0x0E - CMD_BULK_ERASE_PGM = 0x09 - - PROGCMD_SENDINSTR = 1 - PROGCMD_SENDDATA = 2 - PROGCMD_READDATA = 3 - - STAT_BUSY= 0x01 - STAT_SDIO = 0x02 - - def __init__(self, - chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, - signature, - flashPageSize, flashPages, - eepromPageSize, eepromPages, - fuseBytes - ): - Chip.__init__(self, - chipPackage = chipPackage, - chipPinVCC = chipPinVCC, - chipPinsVPP = chipPinsVPP, - chipPinGND = chipPinGND) - self.signature = signature - self.flashPageSize = flashPageSize # Flash page size, in words - self.flashPages = flashPages # Nr of flash pages - self.eepromPageSize = eepromPageSize # EEPROM page size, in bytes - self.eepromPages = eepromPages # Nr of EEPROM pages - self.fuseBytes = fuseBytes # Nr of fuse bytes - self.PC=0 - - - def readSignature(self): - self.progressMeterInit("Reading signature", 0) - signature = self.__readSignature() - self.progressMeterFinish() - return signature - - def erase(self): - self.__erase() - - def __erase(self, keepConfigWord=False): - OSCCAL = 0xfff - if(keepConfigWord): - self.progressMeterInit("Reading ConfigWord for backup", 0) - CW = self.__getConfigWord() - self.progressMeterFinish() - self.__enterPM() - self.progressMeterInit("Reading OSCCAL)", 0) - self.__setPC(self.osccalAddr) - self.__sendReadFlashInstr() - self.top.cmdDelay(0.00005) - self.__readSDOBufferLow() - self.__readSDOBufferHigh() - OSCCAL=self.top.cmdReadBufferReg16() - self.progressMeterFinish() - if(OSCCAL == 0xfff): - self.progressMeterInit("OSCCAL value lost, restoring from backup location ...", 0) - self.__setPC(self.osccalBackupAddr-self.osccalAddr) - self.__sendReadFlashInstr() - self.top.cmdDelay(0.00005) - self.__readSDOBufferLow() - self.__readSDOBufferHigh() - OSCCAL=self.top.cmdReadBufferReg16() - self.progressMeterFinish() - #print ("osccal: %x\n" % OSCCAL) - self.progressMeterInit("Erasing chip", 0) - self.__sendInstr(self.CMD_BULK_ERASE_PGM) - self.top.hostDelay(0.01) #Tera - self.progressMeterFinish() - #OSCCAL=0xC18 - if(OSCCAL != 0xfff): - self.__enterPM() - self.progressMeterInit("Writing osccal, value %x" % OSCCAL, 0) - self.__setPC(self.osccalAddr) - self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) - self.__setSDI(OSCCAL) - self.top.hostDelay(0.000005) - self.__sendWriteFlashInstr() - self.progressMeterFinish() - if(keepConfigWord): - self.progressMeterInit("Write read ConfigWord, value %x" % CW, 0) - self.__writeConfigWord(CW) - self.progressMeterFinish() - - - def readProgmem(self): - nrWords = self.flashPages * self.flashPageSize - image = "" - self.__enterPM() - self.progressMeterInit("Reading flash", nrWords) - bufferedBytes = 0 - for word in range(0, nrWords): - self.__incrementPC(1) - self.__sendReadFlashInstr() - #self.__busyWait() - self.top.cmdDelay(0.00002) #20us wait - inconsistent data if skipped - self.__readSDOBufferLow() - bufferedBytes += 1 - self.__readSDOBufferHigh() - bufferedBytes += 1 - if bufferedBytes == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(bufferedBytes) - self.progressMeter(word) - bufferedBytes = 0 - image += self.top.cmdReadBufferReg(bufferedBytes) - self.progressMeterFinish() - return image - - def writeProgmem(self, image): - nrWords = self.flashPages * self.flashPageSize - if len(image) > nrWords * 2 or len(image) % 2 != 0: - self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\ - (len(image), nrWords * 2)) - self.__enterPM() - self.progressMeterInit("Writing flash", len(image) // 2) - for word in range(0, len(image) // 2): - self.progressMeter(word) - #do not swap following two lines - self.__incrementPC(1) - self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) - WD = (byte2int(image[word * 2 + 1])<<8) | byte2int(image[word * 2 + 0]) - if(WD != 0xfff): - self.__setSDI(WD) - self.top.hostDelay(0.00002) - self.__sendWriteFlashInstr() - - self.progressMeterFinish() - - def readFuse(self): - fuses = [] - self.progressMeterInit("Reading fuses (configuration word)", 0) - CW = self.__getConfigWord() - fuses.append(int2byte(CW & 0x00ff)) - fuses.append(int2byte((CW >> 8) & 0x00ff)) - self.progressMeterFinish() - return b"".join(fuses) - - def __getConfigWord(self): - self.__enterPM() - self.__setPC(self.configWordAddr) - self.__sendReadFlashInstr() - self.top.cmdDelay(0.00002) - self.__readSDOBufferLow() - self.__readSDOBufferHigh() - return self.top.cmdReadBufferReg16() - - def writeFuse(self, image): - if len(image) != 2: - self.throwError("Invalid Fuses image size %d (expected %d)" %\ - (len(image), 2)) - self.progressMeterInit("Writing fuses", 0) - #print "image1:%x,,%x,,%x" % (byte2int(image[0]),byte2int(image[1]),byte2int(image[1])<<8) - self.__writeConfigWord((byte2int(image[1])<<8) | byte2int(image[0])) - self.progressMeterFinish() - - def __writeConfigWord(self, configWord16): - self.__enterPM() - self.__setPC(self.configWordAddr) - self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM) - self.__setSDI(configWord16) - self.top.hostDelay(0.00002) - self.__sendWriteFlashInstr() - - def __readSignature(self): - self.__enterPM() - self.__incrementPC(self.userIDLocationAddr) - for i in range(0, self.userIDLocationSize): - self.__incrementPC(1) - self.__sendReadFlashInstr() - self.top.hostDelay(0.00002) - self.__readSDOBufferLow() - self.__readSDOBufferHigh() - return self.top.cmdReadBufferReg()[0:2*self.userIDLocationSize-1] - - def __enterPM(self): - self.PC = self.logicalFlashSize - 1 - "Enter HV programming mode. Vdd first entry mode" - self.applyVCC(False) - self.applyVPP(False) - self.applyGND(False) - self.__setPins(0,0) - self.top.cmdSetVCCVoltage(self.voltageVDD) - self.top.cmdSetVPPVoltage(self.voltageVPP) - #self.top.cmdEnableZifPullups(True) - self.applyGND(True) - - self.applyVCC(True) - self.top.cmdDelay(0.000005) - - for i in range(0,2): - self.applyVPP(True) - self.top.cmdDelay(0.000005) - self.applyVPP(False) - self.top.cmdDelay(0.000031) - self.applyVPP(True) - #self.top.cmdEnableZifPullups(True) - - self.top.cmdDelay(0.000005) #least 5us is required to reach Vdd first entry PM - - def __checkSignature(self): - signature = self.__readSignature() - if signature != self.signature: - msg = "Unexpected device signature. " +\ - "Want %02X%02X%02X, but got %02X%02X%02X" % \ - (byte2int(self.signature[0]), byte2int(self.signature[1]), - byte2int(self.signature[2]), - byte2int(signature[0]), byte2int(signature[1]), - byte2int(signature[2])) - if self.top.getForceLevel() >= 1: - self.printWarning(msg) - else: - self.throwError(msg) - - def __exitPM(self): - "Exit HV programming mode. Vdd last exit mode" - self.__setPins(0,0) - self.applyVPP(False) - self.applyGND(False) - self.top.hostDelay(0.000005) - self.applyVCC(False) - - def __sendReadFlashInstr(self): - ''' - ''' - self.__sendInstr(self.CMD_READ_DATA_FROM_PGM) - self.__loadCommand(self.PROGCMD_READDATA) - - def __sendWriteFlashInstr(self): - ''' - ''' - self.__loadCommand(self.PROGCMD_SENDDATA) - self.top.hostDelay(0.000005) - self.__sendInstr(self.CMD_BEGIN_PROGRAMMING) - self.top.hostDelay(0.001)#025) #Tprog - self.__sendInstr(self.CMD_END_PROGRAMMING) - self.top.hostDelay(0.0001) #Tdis - - def __sendInstr(self, SDI): - ''' - see __loadCommand for availabla commands - ''' - self.top.cmdFPGAWrite(0x13, SDI & 0xFF) - self.__loadCommand(self.PROGCMD_SENDINSTR) - # We do not poll the busy flag, because that would result - # in a significant slowdown. We delay long enough for the - # command to finish execution, instead. - #self.top.hostDelay(0.001) - self.top.hostDelay(0.000005) - - def __setSDI(self, sdi): - ''' - set 14 bit sdi value - ''' - self.top.cmdFPGAWrite(0x13, sdi & 0xFF) - self.top.cmdFPGAWrite(0x14, (sdi>>8) & 0x0F) - - def __loadCommand(self, command): - ''' - `define CMD_SENDINSTR 1 - `define CMD_SENDDATA 2 - `define CMD_READDATA 3 - ''' - self.top.cmdFPGAWrite(0x12, command & 0xFF) - - def __runCommandSync(self, command): - self.__loadCommand(command) - self.__busyWait() - - def __setPC(self, address): - while(self.PC!=address): - self.__incrementPC(1) - - def __incrementPC(self, count): - for address in range(0, count): - self.__sendInstr(self.CMD_INCREMENT_ADDRESS) - self.PC += 1 - if (self.PC == self.logicalFlashSize): - self.PC = 0 - - def __setPins(self, ICSPCLK=0, SDIODRIVEN=0, SDIOVALUE=0): - ''' - setPins - ''' - data = 0 - if ICSPCLK: - data |= 1 - if SDIODRIVEN: - data |= 2 - if SDIOVALUE: - data |= 4 - self.top.cmdFPGAWrite(0x15, data) - - def __getStatusFlags(self): - ''' - ''' - self.top.cmdFPGARead(0x12) - stat = self.top.cmdReadBufferReg() - return byte2int(stat[0]) - - def __readSDOBufferHigh(self): - self.top.cmdFPGARead(0x10) - - def __readSDOBufferLow(self): - self.top.cmdFPGARead(0x13) - - def __rawSDIOState(self): - return bool(self.__getStatusFlags() & self.STAT_SDIO) - - def __busy(self): - return bool(self.__getStatusFlags() & self.STAT_BUSY) - - def __busyWait(self): - for i in range(0, 100): - if not self.__busy(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout in busywait.") - - def __waitHighSDIO(self): - for i in range(0, 100): - if self.__rawSDOState(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout waiting for SDO.") diff --git a/libtoprammer/chips/pic10f200dip8.py b/libtoprammer/chips/pic10f200dip8.py deleted file mode 100644 index b2ccc2a..0000000 --- a/libtoprammer/chips/pic10f200dip8.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Microchip PIC10F200, PIC10F204 and PI10f220 DIP8 -# -# Copyright (c) 2012 Pavel Stemberk -# -# 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 microchip_common import * - - -class Chip_Pic18F200dip8(Chip_Microchip_common): - voltageVDD = 5 - voltageVPP =13 - #CONFIGURATION WORD FOR PIC10F200/202/204/206 - #X X X X X X X MCLRE /CP WDT X X - logicalFlashSize = 0x200 - userIDLocationSize = 4 - - def __init__(self): - Chip_Microchip_common.__init__(self, - chipPackage = "DIP8", - chipPinVCC = 2, - chipPinsVPP = 8, - chipPinGND = 7, - signature = "\x09\x18\x24\x35", - flashPageSize = 0x100, - flashPages = 1, - eepromPageSize = 0, - eepromPages = 0, - fuseBytes = 2 - ) - self.configWordAddr = self.logicalFlashSize-1 - self.osccalAddr = self.flashPageSize-1 - self.userIDLocationAddr = self.flashPageSize - self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize - -ChipDescription( - Chip_Pic18F200dip8, - bitfile = "pic10fXXXdip8", - chipID = "pic10f200dip8", - runtimeID = (0x000D, 0x01), - chipVendors = "Microchip", - description = "PIC10F200, PIC10F204, PIC10F220", - packages = ( ("DIP8", ""), ), - maintainer = "Pavel Stemberk ", -) diff --git a/libtoprammer/chips/pic10f202dip8.py b/libtoprammer/chips/pic10f202dip8.py deleted file mode 100644 index a7a95e7..0000000 --- a/libtoprammer/chips/pic10f202dip8.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Microchip PIC10F202, PIC10F206 and PIC10f222 DIP8 -# -# Copyright (c) 2012 Pavel Stemberk -# -# 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 microchip_common import * - -class Chip_Pic18F202dip8(Chip_Microchip_common): - voltageVDD = 5 - voltageVPP = 13 - #CONFIGURATION WORD FOR PIC10F200/202/204/206 - #X X X X X X X MCLRE /CP WDT X X - logicalFlashSize = 0x400 - userIDLocationSize = 4 - - def __init__(self): - Chip_Microchip_common.__init__(self, - chipPackage="DIP8", - chipPinVCC=2, - chipPinsVPP=8, - chipPinGND=7, - signature="\x09\x18\x24\x35", - flashPageSize=0x200, - flashPages=1, - eepromPageSize=0, - eepromPages=0, - fuseBytes=2 - ) - self.configWordAddr = self.logicalFlashSize - 1 - self.osccalAddr = self.flashPageSize - 1 - self.userIDLocationAddr = self.flashPageSize - self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize - -ChipDescription( - Chip_Pic18F202dip8, - bitfile = "pic10fXXXdip8", - chipID = "pic10f202dip8", - runtimeID = (0x000D, 0x01), - chipVendors = "Microchip", - description = "PIC10F202, PIC10F206, PIC10F222", - packages = (("DIP8", ""),), - maintainer = "Pavel Stemberk ", -) diff --git a/libtoprammer/fpga/bin/at89s5xdip40.bit b/libtoprammer/fpga/bin/at89s5xdip40.bit new file mode 100644 index 0000000..4e91197 Binary files /dev/null and b/libtoprammer/fpga/bin/at89s5xdip40.bit differ diff --git a/libtoprammer/fpga/bin/microchip01dip14dip20.bit b/libtoprammer/fpga/bin/microchip01dip14dip20.bit new file mode 100644 index 0000000..5e65ed3 Binary files /dev/null and b/libtoprammer/fpga/bin/microchip01dip14dip20.bit differ diff --git a/libtoprammer/fpga/bin/microchip01dip18.bit b/libtoprammer/fpga/bin/microchip01dip18.bit new file mode 100644 index 0000000..9e604f4 Binary files /dev/null and b/libtoprammer/fpga/bin/microchip01dip18.bit differ diff --git a/libtoprammer/fpga/bin/microchip01dip8.bit b/libtoprammer/fpga/bin/microchip01dip8.bit new file mode 100644 index 0000000..1a23f5c Binary files /dev/null and b/libtoprammer/fpga/bin/microchip01dip8.bit differ diff --git a/libtoprammer/fpga/bin/microchip01sip6.bit b/libtoprammer/fpga/bin/microchip01sip6.bit new file mode 100644 index 0000000..22388ed Binary files /dev/null and b/libtoprammer/fpga/bin/microchip01sip6.bit differ diff --git a/libtoprammer/fpga/bin/pic10fXXXdip8.bit b/libtoprammer/fpga/bin/pic10fXXXdip8.bit deleted file mode 100644 index 56b8304..0000000 Binary files a/libtoprammer/fpga/bin/pic10fXXXdip8.bit and /dev/null differ diff --git a/libtoprammer/fpga/bin/pic10fxxxdip8.bit b/libtoprammer/fpga/bin/pic10fxxxdip8.bit new file mode 100644 index 0000000..9e5cb7c Binary files /dev/null and b/libtoprammer/fpga/bin/pic10fxxxdip8.bit differ diff --git a/libtoprammer/fpga/src/at89s5xdip40/Makefile b/libtoprammer/fpga/src/at89s5xdip40/Makefile new file mode 100644 index 0000000..75d7b84 --- /dev/null +++ b/libtoprammer/fpga/src/at89s5xdip40/Makefile @@ -0,0 +1,2 @@ +NAME:=at89s5xdip40 +include ../../common/makefile diff --git a/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.ucf b/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.ucf new file mode 100644 index 0000000..42bb7cc --- /dev/null +++ b/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.ucf @@ -0,0 +1,62 @@ +NET "data<0>" LOC = P30; +NET "data<1>" LOC = P31; +NET "data<2>" LOC = P32; +NET "data<3>" LOC = P34; +NET "data<4>" LOC = P40; +NET "data<5>" LOC = P41; +NET "data<6>" LOC = P43; +NET "data<7>" LOC = P44; + +NET "read" LOC = P45; +NET "write" LOC = P39; +NET "osc_in" LOC = P46; +NET "ale" LOC = P36; + +NET "zif<1>" LOC = P21; +NET "zif<2>" LOC = P19; +NET "zif<3>" LOC = P17; +NET "zif<4>" LOC = P15; +NET "zif<5>" LOC = P10; +NET "zif<6>" LOC = P8; +NET "zif<7>" LOC = P6; +NET "zif<8>" LOC = P4; +NET "zif<9>" LOC = P98; +NET "zif<10>" LOC = P96; +NET "zif<11>" LOC = P93; +NET "zif<12>" LOC = P86; +NET "zif<13>" LOC = P83; +NET "zif<14>" LOC = P81; +NET "zif<15>" LOC = P74; +NET "zif<16>" LOC = P71; +NET "zif<17>" LOC = P69; +NET "zif<18>" LOC = P67; +NET "zif<19>" LOC = P65; +NET "zif<20>" LOC = P60; +NET "zif<21>" LOC = P58; +NET "zif<22>" LOC = P56; +NET "zif<23>" LOC = P54; +NET "zif<24>" LOC = P47; +NET "zif<25>" LOC = P53; +NET "zif<26>" LOC = P55; +NET "zif<27>" LOC = P57; +NET "zif<28>" LOC = P59; +NET "zif<29>" LOC = P62; +NET "zif<30>" LOC = P66; +NET "zif<31>" LOC = P68; +NET "zif<32>" LOC = P70; +NET "zif<33>" LOC = P72; +NET "zif<34>" LOC = P80; +NET "zif<35>" LOC = P82; +NET "zif<36>" LOC = P84; +NET "zif<37>" LOC = P87; +NET "zif<38>" LOC = P95; +NET "zif<39>" LOC = P97; +NET "zif<40>" LOC = P3; +NET "zif<41>" LOC = P5; +NET "zif<42>" LOC = P7; +NET "zif<43>" LOC = P9; +NET "zif<44>" LOC = P13; +NET "zif<45>" LOC = P16; +NET "zif<46>" LOC = P18; +NET "zif<47>" LOC = P20; +NET "zif<48>" LOC = P22; diff --git a/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.v b/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.v new file mode 100644 index 0000000..04f20a7 --- /dev/null +++ b/libtoprammer/fpga/src/at89s5xdip40/at89s5xdip40.v @@ -0,0 +1,326 @@ +/* + * TOP2049 Open Source programming suite + * + * Atmel AT89S5X DIP40 + * FPGA bottomhalf implementation + * + * Copyright (c) 2010 Guido + * 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. + */ + +/* The runtime ID and revision. */ +`define RUNTIME_ID 16'h0005 +`define RUNTIME_REV 16'h01 + +module at89s5xdip40(data, ale, write, read, osc_in, zif); + inout [7:0] data; + input ale; + input write; + input read; + input osc_in; /* 24MHz oscillator */ + inout [48:1] zif; + + /* Interface to the microcontroller */ + wire read_oe; /* Read output-enable */ + reg [7:0] address; /* Cached address value */ + reg [7:0] read_data; /* Cached read data */ + + wire low, high; /* Constant lo/hi */ + + /* Programmer context */ + reg [1:0] prog_busy; + reg [3:0] prog_command; + reg [3:0] prog_state; + reg [3:0] prog_count; + reg prog_err; + + /* DUT signals */ + reg [7:0] dut_data; + reg [13:0] dut_addr; + reg dut_p26; + reg dut_p27; + reg dut_p33; + reg dut_p36; + reg dut_p37; + reg dut_psen; + reg dut_prog; + reg dut_vpp; + reg dut_rst; + wire dut_clock; + + + assign low = 0; + assign high = 1; + + initial begin + prog_busy <= 0; + prog_command <= 0; + prog_state <= 0; + prog_err <= 0; + prog_count <= 0; + dut_data <= 0; + dut_addr <= 0; + dut_p26 <= 0; + dut_p27 <= 0; + dut_p33 <= 0; + dut_p36 <= 0; + dut_p37 <= 0; + dut_psen <= 0; + dut_prog <= 0; + dut_vpp <= 0; + dut_rst <= 0; + end + + /* The delay counter. Based on the 24MHz input clock. */ + reg [15:0] delay_count; + wire osc; + assign dut_clock=osc; + IBUF osc_ibuf(.I(osc_in), .O(osc)); + + always @(posedge osc) begin + if (delay_count == 0) begin + if (prog_busy[0] != prog_busy[1]) begin + /* busy0 != busy1 indicates that a command is running. + * Continue executing it... */ + case (prog_command) + 1: begin /* Set P3.2 after init */ + dut_prog <= 1; + prog_busy[1] <= prog_busy[0]; + end + 2: begin /* clear P3.2 before shutdown */ + dut_prog <= 0; + prog_busy[1] <= prog_busy[0]; + end + 3: begin /* do nPROG pulsep with wait for ready */ + case (prog_state) + 0: begin /* raise dut_prog */ + dut_prog <= 1; + prog_state <= 1; + delay_count <= 48;/*2us (48 tcl) wait*/ + prog_err <= 0; + end + 1: begin /* pulse */ + delay_count <= 24;/* each 1us */ + dut_prog <= 0; + prog_state <= 2; + end + 2: begin /* raise dut_prog */ + dut_prog <= 1; + prog_state <= 3; + prog_count <= 12; + delay_count <= 48;/*2us (48 tcl) wait*/ + end + 3: begin /* wait for ready (zif[14]) == 1 */ + if (zif[14] == 0) begin + delay_count <= 80; /* each 3330ns */ + prog_count <= prog_count - 1; + if (prog_count == 0) begin + prog_err <= 1; + prog_state <= 4; + end + end + else begin + prog_state <= 4; + end + end + 4: begin /* finish */ + prog_state <= 0; + prog_busy[1] <= prog_busy[0]; + end + endcase + end + 4: begin /* do nPROG pulsep */ + case (prog_state) + 0: begin + dut_prog <= 1; + prog_state <= 1; + delay_count <= 48;/*48tcy, 2us*/ + prog_err <= 0; + end + 1: begin /* pulse */ + delay_count <= 24; /* 1us each */ + dut_prog <= 0; + prog_state <= 2; + end + 2: begin + dut_prog <= 1; + prog_state <= 3; + delay_count <= 48;/*48tcy, 2us*/ + end + 3: begin + prog_busy[1] <= prog_busy[0]; + prog_state <= 0; + end + endcase + end + 5: begin /* set dut_vpp */ + dut_vpp <= 1; + prog_busy[1] <= prog_busy[0]; + end + 6: begin /* clear dut_vpp */ + dut_vpp <= 0; + prog_busy[1] <= prog_busy[0]; + end + endcase + end + end else begin + delay_count <= delay_count - 1; + end + end + + always @(posedge write) begin + case (address) + 8'h10: begin + /* Data write */ + dut_data <= data; + end + 8'h11: begin + /* Address LSB write */ + dut_addr[7:0] <= data; + end + 8'h12: begin + /* Address MSB write */ + dut_addr[13:8] <= data[5:0]; + end + 8'h13: begin + /* Run a command. */ + prog_command <= data; + prog_busy[0] <= ~prog_busy[1]; + end + 8'h16: begin + /* Set P26, P27, P33, P36, P37, dut_psen, dut_rst */ + dut_p26 <= data[0]; + dut_p27 <= data[1]; + dut_p33 <= data[2]; + dut_p36 <= data[3]; + dut_p37 <= data[4]; + dut_psen <= data[5]; + dut_rst <= data[6]; + end + endcase + end + + always @(negedge read) begin + case (address) + 8'h10: begin + /* Data read */ + read_data[7] <= zif[36]; + read_data[6] <= zif[37]; + read_data[5] <= zif[38]; + read_data[4] <= zif[39]; + read_data[3] <= zif[40]; + read_data[2] <= zif[41]; + read_data[1] <= zif[42]; + read_data[0] <= zif[43]; + end + 8'h12: begin + /* Read status */ + read_data[0] <= (prog_busy[0] != prog_busy[1]); + read_data[1] <= prog_err; + end + + 8'hFD: read_data <= `RUNTIME_ID & 16'hFF; + 8'hFE: read_data <= (`RUNTIME_ID >> 8) & 16'hFF; + 8'hFF: read_data <= `RUNTIME_REV; + endcase + end + + always @(negedge ale) begin + address <= data; + end + + assign read_oe = !read && address[4]; + + bufif0(zif[1], low, low); + bufif0(zif[2], low, low); + bufif0(zif[3], low, low); + bufif0(zif[4], low, low); + + + + + + + + + + + bufif0(zif[5], dut_addr[0], dut_p26); + bufif0(zif[6], dut_addr[1], dut_p26); + bufif0(zif[7], dut_addr[2], dut_p26); + bufif0(zif[8], dut_addr[3], dut_p26); + bufif0(zif[9], dut_addr[4], dut_p26); + bufif0(zif[10], dut_addr[5], dut_p26); + bufif0(zif[11], dut_addr[6], dut_p26); + bufif0(zif[12], dut_addr[7], dut_p26); + bufif0(zif[13], dut_rst, low); /*Reset*/ + bufif0(zif[14], low, high); /* P3.0 */ + bufif0(zif[15], low, low); /* P3.1 */ + bufif0(zif[16], low, low); /* P3.2 */ + bufif0(zif[17], dut_p33, low); /* P3.3 */ + bufif0(zif[18], low, low); /* P3.4 */ + bufif0(zif[19], low, low); /* P3.5 */ + bufif0(zif[20], dut_p36, low); /* P3.6 */ + bufif0(zif[21], dut_p37, low); /* P3.7 */ + bufif0(zif[22], low, high); /* XTAL2 */ + bufif0(zif[23], dut_clock, low); /* XTAL1 */ + bufif0(zif[24], low, low); /* GND */ + + + + + + + + + + + bufif0(zif[25], dut_addr[8], dut_p26); /* P2.0 */ + bufif0(zif[26], dut_addr[9], dut_p26); /* P2.1 */ + bufif0(zif[27], dut_addr[10], dut_p26); /* P2.2 */ + bufif0(zif[28], dut_addr[11], dut_p26); /* P2.3 */ + bufif0(zif[29], dut_addr[12], dut_p26); /* P2.4 */ + bufif0(zif[30], dut_addr[13], dut_p26); /* P2.5 */ + bufif0(zif[31], dut_p26, low); /* P2.6 */ + bufif0(zif[32], dut_p27, low); /* P2.7 */ + bufif0(zif[33], dut_psen, low); /* !PSEN */ + bufif0(zif[34], dut_prog, low); /* !PROG */ + bufif0(zif[35], low, dut_vpp); /* VPP/Reset */ + bufif0(zif[36], dut_data[7], !(!dut_p26 && dut_p27)); + bufif0(zif[37], dut_data[6], !(!dut_p26 && dut_p27)); + bufif0(zif[38], dut_data[5], !(!dut_p26 && dut_p27)); + bufif0(zif[39], dut_data[4], !(!dut_p26 && dut_p27)); + bufif0(zif[40], dut_data[3], !(!dut_p26 && dut_p27)); + bufif0(zif[41], dut_data[2], !(!dut_p26 && dut_p27)); + bufif0(zif[42], dut_data[1], !(!dut_p26 && dut_p27)); + bufif0(zif[43], dut_data[0], !(!dut_p26 && dut_p27)); + bufif0(zif[44], high, low); /* VCC */ + + bufif0(zif[45], low, low); + bufif0(zif[46], low, low); + bufif0(zif[47], low, low); + bufif0(zif[48], low, low); + + bufif1(data[0], read_data[0], read_oe); + bufif1(data[1], read_data[1], read_oe); + bufif1(data[2], read_data[2], read_oe); + bufif1(data[3], read_data[3], read_oe); + bufif1(data[4], read_data[4], read_oe); + bufif1(data[5], read_data[5], read_oe); + bufif1(data[6], read_data[6], read_oe); + bufif1(data[7], read_data[7], read_oe); +endmodule diff --git a/libtoprammer/fpga/src/microchip01/microchip01.vh b/libtoprammer/fpga/src/microchip01/microchip01.vh new file mode 100644 index 0000000..4424256 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01.vh @@ -0,0 +1,148 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip - version 01 + * FPGA Main bottomhalf implementation + * + * Copyright (c) 2012 Pavel Stemberk + * + * 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. + */ + +`include "common.vh" + +`define DELAY42NSEC(D42NSEC) __delay_count <= (D42NSEC) - 1;//41.666 ns wait cycle if D42NSEC = 1 + +`define CMD_SENDINSTR 1 +`define CMD_SENDDATA 2 +`define CMD_READDATA 3 +`define ALL_WITHOUT_ZIF(NAME_, ID_MAJOR_, ID_MINOR_) \ + `BOTTOMHALF_BEGIN(NAME_, ID_MAJOR_, ID_MINOR_) \ + /* Programmer context */ \ + reg [7:0] prog_count; \ + reg dut_sci_manual; \ + reg dut_sci_auto; \ + wire dut_sci; \ + reg dut_sdio_driven; \ + reg dut_sdio_value; \ + reg dut_vpp; \ + reg [15:0] sdi_buf; \ + reg [15:0] sdo_buf; \ + \ + initial begin \ + prog_count <= 0; \ + dut_sci_manual <= 0; \ + dut_sci_auto <= 0; \ + dut_sdio_driven <= 0; \ + dut_sdio_value <= 0; \ + sdi_buf <= 0; \ + sdo_buf <= 0; \ + dut_vpp <= 0; \ + end \ + \ + `ASYNCPROC_BEGIN \ + if (`CMD_IS_RUNNING) begin \ + case (`CMD_STATE) \ + 0: begin \ + if (`CMD_IS(`CMD_SENDINSTR) || \ + `CMD_IS(`CMD_SENDDATA)) begin \ + dut_sdio_driven <= 1; \ + end else begin \ + dut_sdio_driven <= 0; \ + end \ + `CMD_STATE_SET(1) \ + `DELAY42NSEC(5) \ + end \ + 1: begin \ + dut_sci_auto <= 1; /* CLK hi 80ns after this moment we need to be prepared in CMD_READDATA case */ \ + case(`CMD_NR) \ + `CMD_SENDDATA: begin \ + dut_sdio_value <= sdi_buf[prog_count];\ + end \ + `CMD_SENDINSTR: begin \ + dut_sdio_value <= sdi_buf[prog_count+1];\ + end \ + endcase \ + `CMD_STATE_SET(2) \ + `DELAY42NSEC(5) \ + end \ + 2: begin \ + if (`CMD_IS(`CMD_READDATA)) begin \ + sdo_buf[prog_count] <= zif[`DUT_SDIO];\ + end \ + prog_count <= prog_count + 1; \ + `CMD_STATE_SET(3) \ + `DELAY42NSEC(5) \ + end \ + 3: begin \ + dut_sci_auto <= 0; /* CLK lo */ \ + \ + if ((prog_count == 6 && `CMD_IS(`CMD_SENDINSTR)) ||\ + (prog_count == 16 && (`CMD_IS(`CMD_SENDDATA) ||\ + `CMD_IS(`CMD_READDATA)))) begin\ + `CMD_FINISH \ + prog_count <= 0; \ + if (`CMD_IS(`CMD_SENDINSTR) || \ + `CMD_IS(`CMD_SENDDATA)) begin\ + dut_sdio_driven <= 0; \ + end \ + end else begin \ + if (`CMD_IS(`CMD_READDATA)) begin\ + `DELAY42NSEC(40) \ + end else begin \ + `DELAY42NSEC(5) \ + end \ + `CMD_STATE_SET(0) \ + end \ + end \ + endcase \ + end \ + `ASYNCPROC_END \ + \ + `DATAWRITE_BEGIN \ + `ADDR(2): begin /* Run command */ \ + `CMD_RUN(in_data) \ + end \ + `ADDR(3): begin /* Load SDI LO BYTE sequence */ \ + sdi_buf[0] <= 0; \ + sdi_buf[8:1] <= in_data; \ + end \ + `ADDR(4): begin /* Load SDI HI BYTE sequence */ \ + sdi_buf[14:9] <= in_data[5:0]; \ + sdi_buf[15] <= 0; \ + end \ + `ADDR(5): begin /* Set signals manually */ \ + dut_sci_manual <= in_data[0]; /* SCI */ \ + end \ + `DATAWRITE_END \ + \ + `DATAREAD_BEGIN \ + `ADDR(0): begin /* Get SDO sequence high (bits 8-13) */ \ + out_data[5:0] <= sdo_buf[14:9]; \ + out_data[7:6] <= 0; \ + end \ + `ADDR(2): begin /* Read status */ \ + out_data[0] <= `CMD_IS_RUNNING; /* busy */ \ + out_data[1] <= zif[`DUT_SDIO]; /* Raw SDO pin access */\ + end \ + `ADDR(3): begin /* Get SDO sequence low (bits 0-7) */ \ + out_data[7:0] <= sdo_buf[8:1]; \ + end \ + `DATAREAD_END \ + \ + assign dut_sci = `CMD_IS_RUNNING ? dut_sci_auto : dut_sci_manual; + +/* vim: filetype=verilog:shiftwidth=8:tabstop=8:softtabstop=8 + */ diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/Makefile b/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/Makefile new file mode 100644 index 0000000..2e62a24 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/Makefile @@ -0,0 +1,3 @@ +NAME:=microchip01dip14dip20 +include ../../../common/makefile +COMMONDIR:=../../../common diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/microchip01dip14dip20.v b/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/microchip01dip14dip20.v new file mode 100644 index 0000000..ad65116 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip14dip20/microchip01dip14dip20.v @@ -0,0 +1,76 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip DIP14 and DIP20 implementation + * FPGA bottomhalf implementation + * + * Copyright (c) 2013 Pavel Stemberk + * + * 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. + */ + +`define DUT_SDIO 33 +`include "microchip01.vh" +`ALL_WITHOUT_ZIF(microchip01dip14dip20, 32'hDE03, 1) + + `ZIF_UNUSED(1) + `ZIF_UNUSED(2) + `ZIF_UNUSED(3) + `ZIF_UNUSED(4) + `ZIF_UNUSED(5) + `ZIF_UNUSED(6) + `ZIF_UNUSED(7) + `ZIF_UNUSED(8) + `ZIF_UNUSED(9) + `ZIF_UNUSED(10) + `ZIF_UNUSED(11) + `ZIF_UNUSED(12) + `ZIF_UNUSED(13) + `ZIF_UNUSED(14) + bufif0(zif[15], high, low); /* VCC */ + `ZIF_UNUSED(16) + `ZIF_UNUSED(17) + bufif0(zif[18], low, dut_vpp); /* VPP/Reset */ + `ZIF_UNUSED(19) + `ZIF_UNUSED(20) + `ZIF_UNUSED(21) + `ZIF_UNUSED(22) + `ZIF_UNUSED(23) + `ZIF_UNUSED(24) + `ZIF_UNUSED(25) + `ZIF_UNUSED(26) + `ZIF_UNUSED(27) + `ZIF_UNUSED(28) + `ZIF_UNUSED(29) + `ZIF_UNUSED(30) + `ZIF_UNUSED(31) + bufif0(zif[32], dut_sci, low); /* SCI */ + bufif0(zif[33], dut_sdio_value, !dut_sdio_driven); /* SDO */ + bufif0(zif[34], low, low); /* GND */ + `ZIF_UNUSED(35) + `ZIF_UNUSED(36) + `ZIF_UNUSED(37) + `ZIF_UNUSED(38) + `ZIF_UNUSED(39) + `ZIF_UNUSED(40) + `ZIF_UNUSED(41) + `ZIF_UNUSED(42) + `ZIF_UNUSED(43) + `ZIF_UNUSED(44) + `ZIF_UNUSED(45) + `ZIF_UNUSED(46) + `ZIF_UNUSED(47) + `ZIF_UNUSED(48) +`BOTTOMHALF_END diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip18/Makefile b/libtoprammer/fpga/src/microchip01/microchip01dip18/Makefile new file mode 100644 index 0000000..863e103 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip18/Makefile @@ -0,0 +1,3 @@ +NAME:=microchip01dip18 +include ../../../common/makefile +COMMONDIR:=../../../common diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip18/microchip01dip18.v b/libtoprammer/fpga/src/microchip01/microchip01dip18/microchip01dip18.v new file mode 100644 index 0000000..8d5b005 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip18/microchip01dip18.v @@ -0,0 +1,76 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip DIP18 implementation + * FPGA bottomhalf implementation + * + * Copyright (c) 2013 Pavel Stemberk + * + * 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. + */ + +`define DUT_SDIO 28 +`include "microchip01.vh" +`ALL_WITHOUT_ZIF(microchip01dip18, 32'hDE04, 1) + + `ZIF_UNUSED(1) + `ZIF_UNUSED(2) + `ZIF_UNUSED(3) + `ZIF_UNUSED(4) + `ZIF_UNUSED(5) + `ZIF_UNUSED(6) + `ZIF_UNUSED(7) + `ZIF_UNUSED(8) + `ZIF_UNUSED(9) + `ZIF_UNUSED(10) + `ZIF_UNUSED(11) + `ZIF_UNUSED(12) + `ZIF_UNUSED(13) + `ZIF_UNUSED(14) + `ZIF_UNUSED(15) + `ZIF_UNUSED(16) + `ZIF_UNUSED(17) + `ZIF_UNUSED(15) + bufif0(zif[19], low, dut_vpp); /* VPP/Reset */ + bufif0(zif[20], low, low); /* GND */ + `ZIF_UNUSED(21) + `ZIF_UNUSED(22) + `ZIF_UNUSED(23) + `ZIF_UNUSED(24) + `ZIF_UNUSED(25) + `ZIF_UNUSED(26) + bufif0(zif[27], dut_sci, low); /* SCI */ + bufif0(zif[28], dut_sdio_value, !dut_sdio_driven); /* SDO */ + bufif0(zif[29], high, low); /* VCC */ + `ZIF_UNUSED(30) + `ZIF_UNUSED(31) + `ZIF_UNUSED(32) + `ZIF_UNUSED(33) + `ZIF_UNUSED(34) + `ZIF_UNUSED(35) + `ZIF_UNUSED(36) + `ZIF_UNUSED(37) + `ZIF_UNUSED(38) + `ZIF_UNUSED(39) + `ZIF_UNUSED(40) + `ZIF_UNUSED(41) + `ZIF_UNUSED(42) + `ZIF_UNUSED(43) + `ZIF_UNUSED(44) + `ZIF_UNUSED(45) + `ZIF_UNUSED(46) + `ZIF_UNUSED(47) + `ZIF_UNUSED(48) +`BOTTOMHALF_END diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip8/Makefile b/libtoprammer/fpga/src/microchip01/microchip01dip8/Makefile new file mode 100644 index 0000000..6e0c824 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip8/Makefile @@ -0,0 +1,3 @@ +NAME:=microchip01dip8 +include ../../../common/makefile +COMMONDIR:=../../../common diff --git a/libtoprammer/fpga/src/microchip01/microchip01dip8/microchip01dip8.v b/libtoprammer/fpga/src/microchip01/microchip01dip8/microchip01dip8.v new file mode 100644 index 0000000..a69a1a7 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01dip8/microchip01dip8.v @@ -0,0 +1,54 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip PIC12f50X DIP8 + * FPGA bottomhalf implementation + * + * Copyright (c) 2012 Pavel Stemberk + * + * 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. + */ + +`define DUT_SDIO 27 +`include "microchip01.vh" + +`ALL_WITHOUT_ZIF(microchip01dip8, 32'hDE02, 1) + + `ZIF_UNUSED(1) `ZIF_UNUSED(2) `ZIF_UNUSED(3) + `ZIF_UNUSED(4) `ZIF_UNUSED(5) `ZIF_UNUSED(6) + `ZIF_UNUSED(7) `ZIF_UNUSED(8) `ZIF_UNUSED(9) + `ZIF_UNUSED(10) `ZIF_UNUSED(11) `ZIF_UNUSED(12) + `ZIF_UNUSED(13) `ZIF_UNUSED(14) `ZIF_UNUSED(15) + `ZIF_UNUSED(16) `ZIF_UNUSED(17) `ZIF_UNUSED(18) + `ZIF_UNUSED(19) + `ZIF_UNUSED(20) + bufif0(zif[21], high, low); /* VCC */ + `ZIF_UNUSED(22) + `ZIF_UNUSED(23) + bufif0(zif[24], low, dut_vpp); /* VPP/Reset */ + `ZIF_UNUSED(25) + bufif0(zif[26], dut_sci, low); /* SCI */ + bufif0(zif[27], dut_sdio_value, !dut_sdio_driven); /* SDO */ + bufif0(zif[28], low, low); /* GND */ + `ZIF_UNUSED(29) + `ZIF_UNUSED(30) + `ZIF_UNUSED(31) `ZIF_UNUSED(32) `ZIF_UNUSED(33) + `ZIF_UNUSED(34) + `ZIF_UNUSED(35) `ZIF_UNUSED(36) `ZIF_UNUSED(37) + `ZIF_UNUSED(38) `ZIF_UNUSED(39) `ZIF_UNUSED(40) + `ZIF_UNUSED(41) `ZIF_UNUSED(42) `ZIF_UNUSED(43) + `ZIF_UNUSED(44) `ZIF_UNUSED(45) `ZIF_UNUSED(46) + `ZIF_UNUSED(47) `ZIF_UNUSED(48) +`BOTTOMHALF_END diff --git a/libtoprammer/fpga/src/microchip01/microchip01sip6/Makefile b/libtoprammer/fpga/src/microchip01/microchip01sip6/Makefile new file mode 100644 index 0000000..5656bbd --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01sip6/Makefile @@ -0,0 +1,3 @@ +NAME:=microchip01sip6 +include ../../../common/makefile +COMMONDIR:=../../../common diff --git a/libtoprammer/fpga/src/microchip01/microchip01sip6/microchip01sip6.v b/libtoprammer/fpga/src/microchip01/microchip01sip6/microchip01sip6.v new file mode 100644 index 0000000..724aadc --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/microchip01sip6/microchip01sip6.v @@ -0,0 +1,51 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip ICD2 SIP6 connection (implemented as DIP10) + * FPGA bottomhalf implementation + * + * Copyright (c) 2013 Pavel Stemberk + * + * 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. + */ + +`define DUT_SDIO 27 +`include "microchip01.vh" +`ALL_WITHOUT_ZIF(microchip01sip6, 32'hDE05, 1) + + `ZIF_UNUSED(1) `ZIF_UNUSED(2) `ZIF_UNUSED(3) + `ZIF_UNUSED(4) `ZIF_UNUSED(5) `ZIF_UNUSED(6) + `ZIF_UNUSED(7) `ZIF_UNUSED(8) `ZIF_UNUSED(9) + `ZIF_UNUSED(10) `ZIF_UNUSED(11) `ZIF_UNUSED(12) + `ZIF_UNUSED(13) `ZIF_UNUSED(14) `ZIF_UNUSED(15) + `ZIF_UNUSED(16) `ZIF_UNUSED(17) `ZIF_UNUSED(18) + `ZIF_UNUSED(19) + `ZIF_UNUSED(20) + `ZIF_UNUSED(21) + `ZIF_UNUSED(22) + `ZIF_UNUSED(23) `ZIF_UNUSED(24) `ZIF_UNUSED(25) + bufif0(zif[26], dut_sci, low); /* SCI */ + bufif0(zif[27], dut_sdio_value, !dut_sdio_driven); /* SDO */ + bufif0(zif[28], low, low); /* GND */ + bufif0(zif[29], high, low); /* VCC */ + bufif0(zif[30], low, dut_vpp); /* VPP/Reset */ + `ZIF_UNUSED(31) `ZIF_UNUSED(32) `ZIF_UNUSED(33) + `ZIF_UNUSED(34) + `ZIF_UNUSED(35) `ZIF_UNUSED(36) `ZIF_UNUSED(37) + `ZIF_UNUSED(38) `ZIF_UNUSED(39) `ZIF_UNUSED(40) + `ZIF_UNUSED(41) `ZIF_UNUSED(42) `ZIF_UNUSED(43) + `ZIF_UNUSED(44) `ZIF_UNUSED(45) `ZIF_UNUSED(46) + `ZIF_UNUSED(47) `ZIF_UNUSED(48) +`BOTTOMHALF_END diff --git a/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/Makefile b/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/Makefile new file mode 100644 index 0000000..31547f6 --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/Makefile @@ -0,0 +1,3 @@ +NAME:=pic10fxxxdip8 +include ../../../common/makefile +COMMONDIR:=../../../common diff --git a/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/pic10fxxxdip8.v b/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/pic10fxxxdip8.v new file mode 100644 index 0000000..102fe3a --- /dev/null +++ b/libtoprammer/fpga/src/microchip01/pic10fxxxdip8/pic10fxxxdip8.v @@ -0,0 +1,51 @@ +/* + * TOP2049 Open Source programming suite + * + * Microchip PIC10f200 DIP10 (DIP8, but needs a shift due to GND and Vcc pin placement) + * FPGA bottomhalf implementation + * + * Copyright (c) 2012 Pavel Stemberk + * + * 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. + */ + +`define DUT_SDIO 27 +`include "microchip01.vh" +`ALL_WITHOUT_ZIF(pic10fxxxdip8, 32'hDE01, 1) + + `ZIF_UNUSED(1) `ZIF_UNUSED(2) `ZIF_UNUSED(3) + `ZIF_UNUSED(4) `ZIF_UNUSED(5) `ZIF_UNUSED(6) + `ZIF_UNUSED(7) `ZIF_UNUSED(8) `ZIF_UNUSED(9) + `ZIF_UNUSED(10) `ZIF_UNUSED(11) `ZIF_UNUSED(12) + `ZIF_UNUSED(13) `ZIF_UNUSED(14) `ZIF_UNUSED(15) + `ZIF_UNUSED(16) `ZIF_UNUSED(17) `ZIF_UNUSED(18) + `ZIF_UNUSED(19) + bufif0(zif[20], high, low); /* VCC */ + `ZIF_UNUSED(21) + bufif0(zif[22], dut_sci, low); /* SCI */ + `ZIF_UNUSED(23) `ZIF_UNUSED(24) `ZIF_UNUSED(25) + `ZIF_UNUSED(26) + bufif0(zif[27], dut_sdio_value, !dut_sdio_driven); /* SDO */ + `ZIF_UNUSED(28) + bufif0(zif[29], low, low); /* GND */ + bufif0(zif[30], low, dut_vpp); /* VPP/Reset */ + `ZIF_UNUSED(31) `ZIF_UNUSED(32) `ZIF_UNUSED(33) + `ZIF_UNUSED(34) + `ZIF_UNUSED(35) `ZIF_UNUSED(36) `ZIF_UNUSED(37) + `ZIF_UNUSED(38) `ZIF_UNUSED(39) `ZIF_UNUSED(40) + `ZIF_UNUSED(41) `ZIF_UNUSED(42) `ZIF_UNUSED(43) + `ZIF_UNUSED(44) `ZIF_UNUSED(45) `ZIF_UNUSED(46) + `ZIF_UNUSED(47) `ZIF_UNUSED(48) +`BOTTOMHALF_END diff --git a/libtoprammer/fpga/src/pic10fXXXdip8/Makefile b/libtoprammer/fpga/src/pic10fXXXdip8/Makefile deleted file mode 100644 index 0590886..0000000 --- a/libtoprammer/fpga/src/pic10fXXXdip8/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -NAME:=pic10fXXXdip8 -include ../../common/makefile diff --git a/libtoprammer/fpga/src/pic10fXXXdip8/pic10fXXXdip8.v b/libtoprammer/fpga/src/pic10fXXXdip8/pic10fXXXdip8.v deleted file mode 100644 index 3d39274..0000000 --- a/libtoprammer/fpga/src/pic10fXXXdip8/pic10fXXXdip8.v +++ /dev/null @@ -1,174 +0,0 @@ -/* - * TOP2049 Open Source programming suite - * - * Microchip PIC10f200 DIP10 (DIP8, but needs a shift due to GND and Vcc pin placement) - * FPGA bottomhalf implementation - * - * Copyright (c) 2012 Pavel Stemberk - * - * 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. - */ - -`include "common.vh" - -`define DELAY42NSEC(D42NSEC) __delay_count <= (D42NSEC) - 1;//41.666 ns wait cycle if D42NSEC = 1 - -`BOTTOMHALF_BEGIN(pic10fXXXdip8, 13, 1) - /* Programmer context */ - reg [7:0] prog_count; - `define CMD_SENDINSTR 1 - `define CMD_SENDDATA 2 - `define CMD_READDATA 3 - reg dut_sci_manual; - reg dut_sci_auto; - wire dut_sci; - reg dut_sdio_driven; - reg dut_sdio_value; - reg dut_vpp; - `define DUT_SDIO 27 - reg [15:0] sdi_buf; - reg [15:0] sdo_buf; - - initial begin - prog_count <= 0; - dut_sci_manual <= 0; - dut_sci_auto <= 0; - dut_sdio_driven <= 0; - dut_sdio_value <= 0; - sdi_buf <= 0; - sdo_buf <= 0; - dut_vpp <= 0; - end - - `ASYNCPROC_BEGIN - if (`CMD_IS_RUNNING) begin - case (`CMD_STATE) - 0: begin - if (`CMD_IS(`CMD_SENDINSTR) || - `CMD_IS(`CMD_SENDDATA)) begin - dut_sdio_driven <= 1; - end else begin - dut_sdio_driven <= 0; - end - //dut_vpp <= 1; - `CMD_STATE_SET(1) - `DELAY42NSEC(5) - end - 1: begin - dut_sci_auto <= 1; /* CLK hi */ - /* 80ns after this moment we need to be - * prepared in CMD_READDATA case */ - case(`CMD_NR) - `CMD_SENDDATA: begin - dut_sdio_value <= sdi_buf[prog_count]; - end - `CMD_SENDINSTR: begin - dut_sdio_value <= sdi_buf[prog_count+1]; - end - endcase - `CMD_STATE_SET(2) - `DELAY42NSEC(5) - end - 2: begin - if (`CMD_IS(`CMD_READDATA)) begin - sdo_buf[prog_count] <= zif[`DUT_SDIO]; - end - prog_count <= prog_count + 1; - `CMD_STATE_SET(3) - `DELAY42NSEC(5) - end - 3: begin - dut_sci_auto <= 0; /* CLK lo */ - - if ((prog_count == 6 && `CMD_IS(`CMD_SENDINSTR)) || - (prog_count == 16 && (`CMD_IS(`CMD_SENDDATA) || - `CMD_IS(`CMD_READDATA)))) begin - `CMD_FINISH - prog_count <= 0; - if (`CMD_IS(`CMD_SENDINSTR) || - `CMD_IS(`CMD_SENDDATA)) begin - dut_sdio_driven <= 0; - end - //dut_vpp <= 0; - end else begin - if (`CMD_IS(`CMD_READDATA)) begin - `DELAY42NSEC(40) - end else begin - `DELAY42NSEC(5) - end - `CMD_STATE_SET(0) - end - end - endcase - end - `ASYNCPROC_END - - `DATAWRITE_BEGIN - `ADDR(2): begin /* Run command */ - `CMD_RUN(in_data) - end - `ADDR(3): begin /* Load SDI LO BYTE sequence */ - sdi_buf[0] <= 0; - sdi_buf[8:1] <= in_data; - end - `ADDR(4): begin /* Load SDI HI BYTE sequence */ - sdi_buf[12:9] <= in_data[3:0]; - sdi_buf[15:13] <= 0; - end - `ADDR(5): begin /* Set signals manually */ - dut_sci_manual <= in_data[0]; /* SCI */ - end - `DATAWRITE_END - - `DATAREAD_BEGIN - `ADDR(0): begin /* Get SDO sequence high (bits 8-12) */ - out_data[3:0] <= sdo_buf[12:9]; - out_data[7:4] <= 0; - end - `ADDR(2): begin /* Read status */ - out_data[0] <= `CMD_IS_RUNNING; /* busy */ - out_data[1] <= zif[`DUT_SDIO]; /* Raw SDO pin access */ - end - `ADDR(3): begin /* Get SDO sequence low (bits 0-7) */ - out_data[7:0] <= sdo_buf[8:1]; - end - `DATAREAD_END - - assign dut_sci = `CMD_IS_RUNNING ? dut_sci_auto : dut_sci_manual; - - `ZIF_UNUSED(1) `ZIF_UNUSED(2) `ZIF_UNUSED(3) - `ZIF_UNUSED(4) `ZIF_UNUSED(5) `ZIF_UNUSED(6) - `ZIF_UNUSED(7) `ZIF_UNUSED(8) `ZIF_UNUSED(9) - `ZIF_UNUSED(10) `ZIF_UNUSED(11) `ZIF_UNUSED(12) - `ZIF_UNUSED(13) `ZIF_UNUSED(14) `ZIF_UNUSED(15) - `ZIF_UNUSED(16) `ZIF_UNUSED(17) `ZIF_UNUSED(18) - `ZIF_UNUSED(19) - bufif0(zif[20], high, low); /* VCC */ - `ZIF_UNUSED(21) - bufif0(zif[22], dut_sci, low); /* SCI */ - `ZIF_UNUSED(23) `ZIF_UNUSED(24) `ZIF_UNUSED(25) - `ZIF_UNUSED(26) - bufif0(zif[27], dut_sdio_value, !dut_sdio_driven); /* SDO */ - `ZIF_UNUSED(28) - bufif0(zif[29], low, low); /* GND */ - bufif0(zif[30], low, dut_vpp); /* VPP/Reset */ - `ZIF_UNUSED(31) `ZIF_UNUSED(32) `ZIF_UNUSED(33) - `ZIF_UNUSED(34) - `ZIF_UNUSED(35) `ZIF_UNUSED(36) `ZIF_UNUSED(37) - `ZIF_UNUSED(38) `ZIF_UNUSED(39) `ZIF_UNUSED(40) - `ZIF_UNUSED(41) `ZIF_UNUSED(42) `ZIF_UNUSED(43) - `ZIF_UNUSED(44) `ZIF_UNUSED(45) `ZIF_UNUSED(46) - `ZIF_UNUSED(47) `ZIF_UNUSED(48) -`BOTTOMHALF_END diff --git a/libtoprammer/main.py b/libtoprammer/main.py index 54a72e1..9d44d4c 100644 --- a/libtoprammer/main.py +++ b/libtoprammer/main.py @@ -384,6 +384,23 @@ class TOP(object): self.chip.writeRAM(image) self.flushCommands() self.printDebug("Done writing the image.") + + def readUserIdLocation(self): + """Reads the User ID Location and returns it.""" + self.printDebug("Reading UIL from chip...") + self.checkChip() + image = self.chip.readUserIdLocation() + self.flushCommands() + self.printDebug("Done reading %d bytes." % len(image)) + return image + + def writeUserIdLocation(self, image): + """Writes the User ID Location image to the chip.""" + self.printDebug("Writing %d bytes to UIL of the chip..." % len(image)) + self.checkChip() + self.chip.writeUserIdLocation(image) + self.flushCommands() + self.printDebug("Done writing the image.") def cmdDelay(self, seconds): """Send a delay request to the device. Note that this causes the diff --git a/libtoprammer/util.py b/libtoprammer/util.py index 6d11207..91ec21e 100644 --- a/libtoprammer/util.py +++ b/libtoprammer/util.py @@ -155,10 +155,11 @@ class IO_ihex(object): return False return True - def toBinary(self, ihexData): + def toBinary(self, ihexData, minMaxAddr=None): bin = [] checksumWarned = False doublewriteWarned = False + addrBias = minMaxAddr[0] if minMaxAddr else 0 try: lines = ihexData.splitlines() hiAddr = 0 @@ -201,16 +202,20 @@ class IO_ihex(object): raise TOPException("Invalid IHEX format (inval ELAR)") hiAddr = (int(line[9:11], 16) << 8) | int(line[11:13], 16) continue + if(minMaxAddr and addr < minMaxAddr[0]): + continue + if(minMaxAddr and addr > minMaxAddr[1]): + continue if type == self.TYPE_DATA: - if len(bin) < addr + count: # Reallocate - bin += [b'\xFF'] * (addr + count - len(bin)) + if len(bin) < addr - addrBias + count: # Reallocate + bin += [b'\xFF'] * (addr - addrBias + count - len(bin)) for i in range(9, 9 + count * 2, 2): byte = int2byte(int(line[i:i+2], 16)) - if bin[(i - 9) / 2 + addr] != '\xFF' and \ + if bin[(i - 9) / 2 + addr - addrBias] != '\xFF' and \ not doublewriteWarned: doublewriteWarned = True print "Invalid IHEX format (Wrote twice to same location)" - bin[(i - 9) / 2 + addr] = byte + bin[(i - 9) / 2 + addr - addrBias] = byte continue raise TOPException("Invalid IHEX format (unsup type %d)" % type) except ValueError: diff --git a/toprammer b/toprammer index bdec6ee..a8c736a 100755 --- a/toprammer +++ b/toprammer @@ -58,6 +58,9 @@ def usage(): print " -r|--read-ram FILE Read the RAM" print " -R|--write-ram FILE Write the RAM" print "" + print " -a|--read-uil FILE Read the User ID Location" + print " -A|--write-uil FILE Write the User ID Location" + print "" print "Other options:" print " -t|--list Print a list of supported chips and exit." print " Use -V|--verbose to control the list verbosity (1-4)" @@ -98,7 +101,7 @@ def fileOut(filename, fmtString, data): else: open(filename, "w+b").write(data) -def fileIn(filename, fmtString): +def fileIn(filename, fmtString, minMaxAddr=None): if filename == "-": data = sys.stdin.read() else: @@ -107,7 +110,10 @@ def fileIn(filename, fmtString): handler = IO_autodetect(data)() else: handler = IO_handlers[fmtString]() - return handler.toBinary(data) + if(handler.__class__.__name__== "IO_ihex"): + return handler.toBinary(data, minMaxAddr) + else: + return handler.toBinary(data) def main(argv): opt_verbose = 1 @@ -124,13 +130,14 @@ def main(argv): opt_outformat = "bin" try: (opts, args) = getopt.getopt(sys.argv[1:], - "hc:d:V:Qs:xTp:P:e:E:f:F:o:Ul:L:r:R:BtI:O:C:", + "hc:d:V:Qs:xTp:P:e:E:f:F:o:Ul:L:r:R:BtI:O:C:a:A:", [ "help", "chip-id=", "device=", "verbose=", "noqueue", "read-sig=", "erase", "test", "read-prog=", "write-prog=", "read-eeprom=", "write-eeprom=", "read-fuse=", "write-fuse=", "read-lock=", "write-lock=", "read-ram=", "write-ram=", "force=", "force-upload", "broken", "list", - "in-format=", "out-format=", "chip-opt=", ]) + "in-format=", "out-format=", "chip-opt=", + "read-uil=", "write-uil=" ]) for (o, v) in opts: if o in ("-h", "--help"): usage() @@ -208,6 +215,12 @@ def main(argv): if o in ("-R", "--write-ram"): opt_action = "write-ram" opt_file = v + if o in ("-a", "--read-uil"): + opt_action = "read-uil" + opt_file = v + if o in ("-A", "--write-uil"): + opt_action = "write-uil" + opt_file = v except (getopt.GetoptError, ValueError), e: usage() return 1 @@ -246,7 +259,15 @@ def main(argv): elif opt_action == "read-prog": fileOut(opt_file, opt_outformat, top.readProgmem()) elif opt_action == "write-prog": - top.writeProgmem(fileIn(opt_file, opt_informat)) + if(hasattr(top.getChip(),'programMemoryByteAddressRange')): #FIXME UGLY! + for minMaxAddr in top.getChip().programMemoryByteAddressRange: + print "trying %x, %x\n" % minMaxAddr + image = fileIn(opt_file, opt_informat, minMaxAddr) + if(len(image)>0): + break + else: + image = fileIn(opt_file, opt_informat) + top.writeProgmem(image) elif opt_action == "read-eeprom": fileOut(opt_file, opt_outformat, top.readEEPROM()) elif opt_action == "write-eeprom": @@ -254,7 +275,15 @@ def main(argv): elif opt_action == "read-fuse": fileOut(opt_file, opt_outformat, top.readFuse()) elif opt_action == "write-fuse": - top.writeFuse(fileIn(opt_file, opt_informat)) + if(hasattr(top.getChip(),'configWordByteAddressRange')): #FIXME UGLY! + for minMaxAddr in top.getChip().configWordByteAddressRange: + print "trying %x, %x\n" % minMaxAddr + image = fileIn(opt_file, opt_informat, minMaxAddr) + if(len(image)>0): + break + else: + image = fileIn(opt_file, opt_informat) + top.writeFuse(image) elif opt_action == "read-lock": fileOut(opt_file, opt_outformat, top.readLockbits()) elif opt_action == "write-lock": @@ -263,6 +292,10 @@ def main(argv): fileOut(opt_file, opt_outformat, top.readRAM()) elif opt_action == "write-ram": top.writeRAM(fileIn(opt_file, opt_informat)) + elif opt_action == "read-uil": + fileOut(opt_file, opt_outformat, top.readUserIdLocation()) + elif opt_action == "write-uil": + top.writeUserIdLocation(fileIn(opt_file, opt_informat)) else: print "No action specified" top.shutdownChip() diff --git a/toprammer-gui b/toprammer-gui index 609c73d..a921aeb 100755 --- a/toprammer-gui +++ b/toprammer-gui @@ -856,9 +856,8 @@ class HwThread(QThread): layoutGen = chip.getLayoutGenerator() if layoutGen: asciiArtLayout = layoutGen.zifLayoutAsciiArt() - chipSupportFlags = chip.getSupportFlags() self.__unblockCancellation() - retval = (chipSupportFlags, asciiArtLayout) + retval = (chip, asciiArtLayout) elif task == self.TASK_READALL: self.top.checkChip() supportFlags = self.top.getChip().getSupportFlags() @@ -2128,7 +2127,7 @@ class MainWindow(QMainWindow): self.guiDisable = 0 self.inputEventsBlocked = 0 - self.chipSupportFlags = 0 # Chip.SUPPORT_... for the loaded chip + self.chip = None # Chip instance self.currentChipDescription = None self.previousRawCommand = "" @@ -2298,6 +2297,7 @@ class MainWindow(QMainWindow): def loadBuffer(self): bufWidget = self.bufferTab.getCurrentBuffer() + data = None if not bufWidget: return if bufWidget.isReadOnly(): @@ -2318,7 +2318,7 @@ class MainWindow(QMainWindow): extensions = str(selectedFilter).split("(")[1].\ split(")")[0].replace("*", "").strip().split() try: - data = open(fn, "rb").read() + dataIn = open(fn, "rb").read() except (IOError), e: QMessageBox.critical(self, "Failed to read file", "Failed to read %s:\n%s" %\ @@ -2326,14 +2326,33 @@ class MainWindow(QMainWindow): return try: if ".bin" in extensions: - data = IO_binary().toBinary(data) # no-op - elif ".ihex" in extensions: - data = IO_ihex().toBinary(data) + data = IO_binary().toBinary(dataIn) # no-op elif ".ahex" in extensions: - data = IO_ahex().toBinary(data) - elif not extensions: # auto - handler = IO_autodetect(data)() - data = handler.toBinary(data) + data = IO_ahex().toBinary(dataIn) + elif (not extensions or ".ihex" in extensions): # auto + if ".ihex" in extensions: + handler = IO_ihex() + else: + handler = IO_autodetect(dataIn)() + #FIXME UGLY! + if(handler.__class__.__name__== "IO_ihex"): + if(bufWidget.__class__.__name__=='ImageBufferWidget' and hasattr(self.chip,'programMemoryByteAddressRange')): + for minMaxAddr in self.chip.programMemoryByteAddressRange: + print "trying %x, %x\n" % minMaxAddr + data = handler.toBinary(dataIn, minMaxAddr) + if(len(data)>0): + break + elif(bufWidget.__class__.__name__ =='BitBufferWidget' and hasattr(self.chip,'configWordByteAddressRange')): + for minMaxAddr in self.chip.configWordByteAddressRange: + print "trying %x, %x\n" % minMaxAddr + data = handler.toBinary(dataIn, minMaxAddr) + if(len(data)>0): + break + print "failed" + else: + data = handler.toBinary(dataIn) + else: + data = handler.toBinary(dataIn) else: assert(0) except (TOPException), e: @@ -2525,22 +2544,22 @@ class MainWindow(QMainWindow): # Task succeed if self.operation == self.OP_INITCHIP: assert(task == HwThread.TASK_INITCHIP) - (self.chipSupportFlags, asciiArtLayout) = returnValue - self.bufferTab.setupBuffers(self.chipSupportFlags) + (self.chip, asciiArtLayout) = returnValue + self.bufferTab.setupBuffers(self.chip.getSupportFlags()) self.bufferTab.infoBuffer.clear() self.bufferTab.infoBuffer.setupDescription(self.currentChipDescription) self.bufferTab.infoBuffer.setChipLayout(asciiArtLayout) - self.autorun.setup(self.chipSupportFlags) - self.topToolBar.setup(self.chipSupportFlags) - self.rightToolBar.setup(self.chipSupportFlags) - self.setupRunMenu(self.chipSupportFlags) + self.autorun.setup(self.chip.getSupportFlags()) + self.topToolBar.setup(self.chip.getSupportFlags()) + self.rightToolBar.setup(self.chip.getSupportFlags()) + self.setupRunMenu(self.chip.getSupportFlags()) elif self.operation == self.OP_SHUTDOWN: pass # Nothing to do elif self.operation == self.OP_READALL: assert(task == HwThread.TASK_READALL) (sigImage, progmemImage, eepromImage, fuseImage, lockbitsImage, ramImage) = returnValue - self.bufferTab.setupBuffers(self.chipSupportFlags) + self.bufferTab.setupBuffers(self.chip.getSupportFlags()) self.bufferTab.loadBuffers(progmemImage, eepromImage, fuseImage, lockbitsImage, ramImage) -- cgit v1.2.3