From c9b74898f30ba1218e2e683151fb082d3bc35fd5 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Fri, 6 Apr 2012 23:23:11 +0200 Subject: Move chip algorithms to submodule Signed-off-by: Michael Buesch --- README-DEVELOPERS.lyx | 13 +- README-DEVELOPERS.ps | 77 +++--- libtoprammer/chip_74hc4094.py | 150 ----------- libtoprammer/chip_at27c256r.py | 82 ------ libtoprammer/chip_at89c2051dip20.py | 230 ----------------- libtoprammer/chip_atmega32dip40.py | 47 ---- libtoprammer/chip_atmega88dip28.py | 47 ---- libtoprammer/chip_atmega8dip28.py | 79 ------ libtoprammer/chip_atmega_common.py | 465 ----------------------------------- libtoprammer/chip_attiny13dip8.py | 358 --------------------------- libtoprammer/chip_attiny26dip20.py | 48 ---- libtoprammer/chip_generic_sram.py | 122 --------- libtoprammer/chip_hm62256dip28.py | 45 ---- libtoprammer/chip_m24cxxdip8.py | 260 -------------------- libtoprammer/chip_m2764a.py | 173 ------------- libtoprammer/chip_m8cissp.py | 457 ---------------------------------- libtoprammer/chip_unitest.py | 171 ------------- libtoprammer/chip_w29ee011dip32.py | 254 ------------------- libtoprammer/chip_xxxx.py | 15 -- libtoprammer/chips/_74hc4094.py | 150 +++++++++++ libtoprammer/chips/__init__.py | 15 ++ libtoprammer/chips/at27c256r.py | 82 ++++++ libtoprammer/chips/at89c2051dip20.py | 230 +++++++++++++++++ libtoprammer/chips/atmega32dip40.py | 47 ++++ libtoprammer/chips/atmega88dip28.py | 47 ++++ libtoprammer/chips/atmega8dip28.py | 79 ++++++ libtoprammer/chips/atmega_common.py | 465 +++++++++++++++++++++++++++++++++++ libtoprammer/chips/attiny13dip8.py | 358 +++++++++++++++++++++++++++ libtoprammer/chips/attiny26dip20.py | 48 ++++ libtoprammer/chips/generic_sram.py | 122 +++++++++ libtoprammer/chips/hm62256dip28.py | 45 ++++ libtoprammer/chips/m24cxxdip8.py | 260 ++++++++++++++++++++ libtoprammer/chips/m2764a.py | 173 +++++++++++++ libtoprammer/chips/m8cissp.py | 457 ++++++++++++++++++++++++++++++++++ libtoprammer/chips/unitest.py | 171 +++++++++++++ libtoprammer/chips/w29ee011dip32.py | 254 +++++++++++++++++++ libtoprammer/layout_generator.py | 2 +- libtoprammer/top_devices.py | 6 + libtoprammer/top_xxxx.py | 6 - libtoprammer/toprammer_main.py | 4 +- setup.py | 2 +- 41 files changed, 3061 insertions(+), 3055 deletions(-) delete mode 100644 libtoprammer/chip_74hc4094.py delete mode 100644 libtoprammer/chip_at27c256r.py delete mode 100644 libtoprammer/chip_at89c2051dip20.py delete mode 100644 libtoprammer/chip_atmega32dip40.py delete mode 100644 libtoprammer/chip_atmega88dip28.py delete mode 100644 libtoprammer/chip_atmega8dip28.py delete mode 100644 libtoprammer/chip_atmega_common.py delete mode 100644 libtoprammer/chip_attiny13dip8.py delete mode 100644 libtoprammer/chip_attiny26dip20.py delete mode 100644 libtoprammer/chip_generic_sram.py delete mode 100644 libtoprammer/chip_hm62256dip28.py delete mode 100644 libtoprammer/chip_m24cxxdip8.py delete mode 100644 libtoprammer/chip_m2764a.py delete mode 100644 libtoprammer/chip_m8cissp.py delete mode 100644 libtoprammer/chip_unitest.py delete mode 100644 libtoprammer/chip_w29ee011dip32.py delete mode 100644 libtoprammer/chip_xxxx.py create mode 100644 libtoprammer/chips/_74hc4094.py create mode 100644 libtoprammer/chips/__init__.py create mode 100644 libtoprammer/chips/at27c256r.py create mode 100644 libtoprammer/chips/at89c2051dip20.py create mode 100644 libtoprammer/chips/atmega32dip40.py create mode 100644 libtoprammer/chips/atmega88dip28.py create mode 100644 libtoprammer/chips/atmega8dip28.py create mode 100644 libtoprammer/chips/atmega_common.py create mode 100644 libtoprammer/chips/attiny13dip8.py create mode 100644 libtoprammer/chips/attiny26dip20.py create mode 100644 libtoprammer/chips/generic_sram.py create mode 100644 libtoprammer/chips/hm62256dip28.py create mode 100644 libtoprammer/chips/m24cxxdip8.py create mode 100644 libtoprammer/chips/m2764a.py create mode 100644 libtoprammer/chips/m8cissp.py create mode 100644 libtoprammer/chips/unitest.py create mode 100644 libtoprammer/chips/w29ee011dip32.py create mode 100644 libtoprammer/top_devices.py delete mode 100644 libtoprammer/top_xxxx.py diff --git a/README-DEVELOPERS.lyx b/README-DEVELOPERS.lyx index 76f48d6..d322402 100644 --- a/README-DEVELOPERS.lyx +++ b/README-DEVELOPERS.lyx @@ -469,12 +469,16 @@ The DUT specific top-half lives in the \begin_inset Quotes eld \end_inset -chip_xxx.py +libtoprammer/chips \begin_inset Quotes erd \end_inset - files, where xxx is the ID of the DUT. - This file contains a class derived from the + module. + The files in that module contain the top-half algorithm implementation. + The files are named after the chip ID. + Make sure to update the __init__.py of the module when adding algorithm + implementations. + The top-half files contain a class derived from the \begin_inset Quotes eld \end_inset @@ -491,8 +495,7 @@ Chip \begin_inset Quotes erd \end_inset - class provides some basic helper methods for algorithm implementation. - It also defines the interface that is to be re-implemented in the derived + class defines the interface that is to be re-implemented in the derived subclass. This interface consists of the following methods: \end_layout diff --git a/README-DEVELOPERS.ps b/README-DEVELOPERS.ps index 06cd9ae..d9d21d5 100644 --- a/README-DEVELOPERS.ps +++ b/README-DEVELOPERS.ps @@ -1,7 +1,7 @@ %!PS-Adobe-2.0 %%Creator: dvips(k) 5.991 Copyright 2011 Radical Eye Software %%Title: README-DEVELOPERS.dvi -%%CreationDate: Fri Apr 6 21:24:07 2012 +%%CreationDate: Fri Apr 6 23:20:54 2012 %%Pages: 7 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 @@ -11,7 +11,7 @@ %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -o README-DEVELOPERS.ps README-DEVELOPERS.dvi %DVIPSParameters: dpi=600 -%DVIPSSource: TeX output 2012.04.06:2124 +%DVIPSSource: TeX output 2012.04.06:2320 %%BeginProcSet: tex.pro 0 0 %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S @@ -3480,54 +3480,57 @@ b(The)26 b(dela)n(y)f(is)h(p)r(erformed)g(on)g(the)g(host)g(computer)g %%Page: 4 4 TeXDict begin 4 3 bop 515 523 a Fd(not)29 b(sending)g(commands)f(to)h (the)h(programmer)d(for)i(the)g(time)h(sp)r(eci\034ed)f(after)g -(\035ushing)515 623 y(the)f(command)f(queue.)515 897 -y Ff(4)131 b(TX)44 b(command)f(queueing)515 1079 y Fd(All)29 +(\035ushing)515 623 y(the)f(command)f(queue.)515 894 +y Ff(4)131 b(TX)44 b(command)f(queueing)515 1076 y Fd(All)29 b(commands)f(transmitted)h(to)f(the)h(device)g(are)e(not)i(sen)n(t)g -(immediately)-7 b(,)29 b(but)g(queued)515 1179 y(in)f(soft)n(w)n(are)f +(immediately)-7 b(,)29 b(but)g(queued)515 1176 y(in)f(soft)n(w)n(are)f (and)h(sen)n(t)h(later.)38 b(This)29 b(is)f(done)g(to)g(sp)r(eed)h(up)g -(device)f(access)f(signi\034can)n(tly)-7 b(.)515 1278 +(device)f(access)f(signi\034can)n(tly)-7 b(.)515 1275 y(The)27 b(command)g(transmission)g(queue)g(has)g(sev)n(eral)f -(\035ushing)h(conditions:)639 1444 y Fc(\017)41 b Fd(Commands)18 +(\035ushing)h(conditions:)639 1428 y Fc(\017)41 b Fd(Commands)18 b(can)g(b)r(e)h(\035ushed)f(explicitely)h(using)f(the)g -(\020\035ushCommands\(\)\021)25 b(metho)r(d)722 1544 -y(of)j(\020class)e(TOP\021.)639 1710 y Fc(\017)41 b Fd(Commands)18 +(\020\035ushCommands\(\)\021)25 b(metho)r(d)722 1528 +y(of)j(\020class)e(TOP\021.)639 1687 y Fc(\017)41 b Fd(Commands)18 b(are)g(automatically)f(\035ushed)i(on)g(cmdReadBu\033erReg\(\))f(b)r -(efore)g(read-)722 1810 y(ing)30 b(the)h(data)f(from)g(the)h(device.)45 +(efore)g(read-)722 1787 y(ing)30 b(the)h(data)f(from)g(the)h(device.)45 b(This)30 b(is)g(to)g(ensure)g(sequen)n(tial)g(consistency)f(of)722 -1909 y(the)f(commands.)639 2075 y Fc(\017)41 b Fd(Commands)27 +1886 y(the)f(commands.)639 2045 y Fc(\017)41 b Fd(Commands)27 b(are)g(\035ushed)h(on)f(v)-5 b(arious)26 b(v)n(oltage-la)n(y)n(out)e -(op)r(erations.)515 2241 y(Y)-7 b(ou)27 b(usually)g(do)h(not)f(need)h -(to)f(\035ush)h(commands)f(explicitely)-7 b(.)515 2516 +(op)r(erations.)515 2198 y(Y)-7 b(ou)27 b(usually)g(do)h(not)f(need)h +(to)f(\035ush)h(commands)f(explicitely)-7 b(.)515 2470 y Ff(5)131 b(Implemen)l(ting)44 b(a)g(new)f(c)l(hip)j(\(DUT\))e -(algorithm)515 2698 y Fd(The)32 b(reading)f(and)g(programming)f +(algorithm)515 2652 y Fd(The)32 b(reading)f(and)g(programming)f (algorithms)h(for)g(the)i(c)n(hips)e(\(DUT)-7 b(s\))33 -b(are)e(separated)515 2797 y(in)n(to)c(t)n(w)n(o)g(parts:)639 -2963 y Fc(\017)41 b Fd(Lo)n(w)27 b(lev)n(el)g(FPGA)i(b)r(ottom-half)639 -3129 y Fc(\017)41 b Fd(High)28 b(lev)n(el)f(Python)h(co)r(de)f -(top-half)515 3295 y(The)35 b(FPGA)i(b)r(ottom-half)f(implemen)n(ts)f +b(are)e(separated)515 2751 y(in)n(to)c(t)n(w)n(o)g(parts:)639 +2904 y Fc(\017)41 b Fd(Lo)n(w)27 b(lev)n(el)g(FPGA)i(b)r(ottom-half)639 +3063 y Fc(\017)41 b Fd(High)28 b(lev)n(el)f(Python)h(co)r(de)f +(top-half)515 3216 y(The)35 b(FPGA)i(b)r(ottom-half)f(implemen)n(ts)f (the)h(basic)f(op)r(erations)g(\(fetc)n(hing)g(data)g(from)515 -3395 y(DUT.)27 b(W)-7 b(riting)26 b(data)g(to)g(DUT.)h(etc...\).)37 +3315 y(DUT.)27 b(W)-7 b(riting)26 b(data)g(to)g(DUT.)h(etc...\).)37 b(It)27 b(ma)n(y)f(also)f(implemen)n(t)i(timingcritical)f(parts)515 -3495 y(of)e(the)h(algorithm.)34 b(Ev)n(erything)24 b(else)g(is)g +3415 y(of)e(the)h(algorithm.)34 b(Ev)n(erything)24 b(else)g(is)g (implemen)n(ted)h(in)f(the)h(high)f(lev)n(el)g(Python)g(co)r(de,)515 -3594 y(that)k(liv)n(es)e(on)i(the)g(other)f(end)g(of)h(the)g(USB)g -(line.)515 3827 y Fb(5.1)112 b(Python)37 b(top-half)h(implemen)m -(tation)515 3980 y Fd(The)27 b(DUT)i(sp)r(eci\034c)e(top-half)h(liv)n -(es)f(in)h(the)g(\020c)n(hip_xxx.p)n(y\021)k(\034les,)c(where)f(xxx)g -(is)h(the)g(ID)515 4080 y(of)23 b(the)h(DUT.)h(This)e(\034le)h(con)n -(tains)f(a)g(class)g(deriv)n(ed)g(from)g(the)h(\020Chip\021)30 -b(class.)35 b(The)24 b(\020Chip\021)515 4179 y(class)g(pro)n(vides)g -(some)h(basic)g(help)r(er)g(metho)r(ds)h(for)f(algorithm)f(implemen)n -(tation.)36 b(It)26 b(also)515 4279 y(de\034nes)h(the)h(in)n(terface)f -(that)h(is)f(to)h(b)r(e)f(re-implemen)n(ted)h(in)f(the)h(deriv)n(ed)f -(sub)r(class.)36 b(This)515 4378 y(in)n(terface)27 b(consists)f(of)i -(the)g(follo)n(wing)e(metho)r(ds:)515 4544 y Fe(sh)m(utdo)m(wnChip\(\)) -41 b Fd(Called)26 b(once)f(on)g(c)n(hip)h(sh)n(utdo)n(wn.)35 -b(The)26 b(default)g(implemen)n(tation)722 4644 y(turns)i(o\033)f(all)h -(v)n(oltages.)34 b(There's)27 b(usually)g(no)h(need)f(to)h(o)n(v)n -(erride)d(that.)515 4810 y Fe(readSignature\(\))42 b +3515 y(that)k(liv)n(es)e(on)i(the)g(other)f(end)g(of)h(the)g(USB)g +(line.)515 3744 y Fb(5.1)112 b(Python)37 b(top-half)h(implemen)m +(tation)515 3897 y Fd(The)19 b(DUT)h(sp)r(eci\034c)g(top-half)f(liv)n +(es)g(in)h(the)g(\020libtoprammer/c)n(hips\021)k(mo)r(dule.)34 +b(The)19 b(\034les)h(in)515 3997 y(that)g(mo)r(dule)g(con)n(tain)e(the) +i(top-half)g(algorithm)e(implemen)n(tation.)34 b(The)20 +b(\034les)g(are)e(named)515 4097 y(after)30 b(the)h(c)n(hip)g(ID.)g +(Mak)n(e)f(sure)g(to)g(up)r(date)h(the)g(__init__.p)n(y)e(of)i(the)g +(mo)r(dule)g(when)515 4196 y(adding)k(algorithm)f(implemen)n(tations.) +61 b(The)35 b(top-half)h(\034les)f(con)n(tain)g(a)g(class)g(deriv)n(ed) +515 4296 y(from)d(the)g(\020Chip\021)39 b(class.)50 b(The)33 +b(\020Chip\021)38 b(class)32 b(de\034nes)g(the)h(in)n(terface)e(that)i +(is)f(to)g(b)r(e)h(re-)515 4395 y(implemen)n(ted)j(in)g(the)g(deriv)n +(ed)e(sub)r(class.)61 b(This)35 b(in)n(terface)g(consists)g(of)g(the)h +(follo)n(wing)515 4495 y(metho)r(ds:)515 4648 y Fe(sh)m(utdo)m +(wnChip\(\))41 b Fd(Called)26 b(once)f(on)g(c)n(hip)h(sh)n(utdo)n(wn.) +35 b(The)26 b(default)g(implemen)n(tation)722 4747 y(turns)i(o\033)f +(all)h(v)n(oltages.)34 b(There's)27 b(usually)g(no)h(need)f(to)h(o)n(v) +n(erride)d(that.)515 4907 y Fe(readSignature\(\))42 b Fd(Read)31 b(the)i(DUT)f(signature)f(and)g(return)h(it.)49 -b(Reimplemen)n(t)33 b(this,)722 4910 y(if)28 b(y)n(our)f(DUT)h(supp)r +b(Reimplemen)n(t)33 b(this,)722 5006 y(if)28 b(y)n(our)f(DUT)h(supp)r (orts)f(signature)f(reading.)1926 5255 y(4)p eop end %%Page: 5 5 TeXDict begin 5 4 bop 515 523 a Fe(erase\(\))41 b Fd(Erase)d(the)g diff --git a/libtoprammer/chip_74hc4094.py b/libtoprammer/chip_74hc4094.py deleted file mode 100644 index 6bc6478..0000000 --- a/libtoprammer/chip_74hc4094.py +++ /dev/null @@ -1,150 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# 74HC4094 unit-tester -# -# Copyright (c) 2011 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_unitest import * - -class Chip_74hc4094(Chip_Unitest): - def __init__(self): - Chip_Unitest.__init__(self, chipPackage="DIP16", - chipPinVCC=16, - chipPinGND=8, - VCCVoltage=5) - - def __initChip(self): - self.zifPin_STR = self.generator.getZifPinForPackagePin(1) - self.zifPin_D = self.generator.getZifPinForPackagePin(2) - self.zifPin_CP = self.generator.getZifPinForPackagePin(3) - self.zifPin_OE = self.generator.getZifPinForPackagePin(15) - self.zifPin_QS1 = self.generator.getZifPinForPackagePin(9) - self.zifPin_QS2 = self.generator.getZifPinForPackagePin(10) - self.zifPins_QP = [] - for packagePin in (4, 5, 6, 7, 14, 13, 12, 11): - self.zifPins_QP.append( - self.generator.getZifPinForPackagePin(packagePin)) - - self.reset() - - outen = 0 - for zifPin in (self.zifPin_STR, self.zifPin_D, - self.zifPin_CP, self.zifPin_OE): - outen |= (1 << (zifPin - 1)) - self.setOutputEnableMask(outen) - - self.applyGND(True) - self.applyVCC(True) - - def test(self): - testPatterns = (0xFF, 0x00, 0xAA, 0x55, 0xF0, 0x0F, - 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00) - - self.progressMeterInit("Logic test", len(testPatterns)) - self.__initChip() - - # Initialize the register to all-zero - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) - for i in range(0, 9): - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=1, OE=0)) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) - self.setOutputs(self.__makeOutMask(STR=1, D=0, CP=0, OE=0)) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=1)) - - QP = self.__readQP() - if QP != 0x00: - self.throwError("Failed to clear the shiftregister. Got 0x%02X" % QP) - - prevContents = 0x00 - prev_QS1 = False - count = 0 - for testPattern in testPatterns: - self.progressMeter(count) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) - for bitNr in range(7, -1, -1): # MSB first - self.setOutputs(self.__makeOutMask(STR=0, - D=(testPattern & (1 << bitNr)), - CP=0, OE=0)) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=1, OE=0)) - (QS1, QS2) = self.__readQS() - word = (prevContents << 8) | testPattern - expect_QS1 = bool(word & (1 << (bitNr + 7))) - expect_QS2 = prev_QS1 - prev_QS1 = expect_QS1 - if QS1 != expect_QS1 or QS2 != expect_QS2: - self.throwError("Got invalid QS serial output for " - "test pattern 0x%02X bit %d. Got %d/%d, but " - "expected %d/%d" %\ - (testPattern, bitNr, QS1, QS2, - expect_QS1, expect_QS2)) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) - self.setOutputs(self.__makeOutMask(STR=1, D=0, CP=0, OE=0)) - self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=1)) - - QP = self.__readQP() - if QP != testPattern: - self.throwError("Failed on test pattern 0x%02X. Got 0x%02X" %\ - (testPattern, QP)) - - prevContents = testPattern - count += 1 - self.progressMeterFinish() - - def __makeOutMask(self, STR, D, CP, OE): - mask = 0 - if STR: - mask |= (1 << (self.zifPin_STR - 1)) - if D: - mask |= (1 << (self.zifPin_D - 1)) - if CP: - mask |= (1 << (self.zifPin_CP - 1)) - if OE: - mask |= (1 << (self.zifPin_OE - 1)) - return mask - - def __readQP(self): - QPValue = 0 - count = 0 - inputs = self.getInputs() - for zifPin in self.zifPins_QP: - if inputs & (1 << (zifPin - 1)): - QPValue |= (1 << count) - count += 1 - return QPValue - - def __readQS(self): - QS1 = False - QS2 = False - inputs = self.getInputs() - if inputs & (1 << (self.zifPin_QS1 - 1)): - QS1 = True - if inputs & (1 << (self.zifPin_QS2 - 1)): - QS2 = True - return (QS1, QS2) - -ChipDescription( - Chip_74hc4094, - chipID = "74hc4094dip16", - bitfile = "unitest", - runtimeID = (0x0008, 0x01), - chipType = ChipDescription.TYPE_LOGIC, - description = "74HC(T)4094 shift-register", - chipVendors = ("Philips", "Other"), -) diff --git a/libtoprammer/chip_at27c256r.py b/libtoprammer/chip_at27c256r.py deleted file mode 100644 index b3c351d..0000000 --- a/libtoprammer/chip_at27c256r.py +++ /dev/null @@ -1,82 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel AT27C256R EPROM -# -# Copyright (c) 2012 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_at27c256r(Chip): - def __init__(self): - Chip.__init__(self, - chipPackage = "DIP28", - chipPinVCC = 28, - chipPinsVPP = 1, - chipPinGND = 14) - self.sizeBytes = 32 * 1024 - self.generic = GenericAlgorithms(self) - self.addrSetter = AddrSetter(self, 0x10, 0x11) - - def readEEPROM(self): - self.__turnOn() - return self.generic.simpleReadEPROM( - sizeBytes = self.sizeBytes, - readData8Func = self.__dataRead, - addrSetter = self.addrSetter, - initFunc = lambda: self.__setFlags(oe=0, ce=0), - exitFunc = lambda: self.__setFlags(oe=1, ce=1) - ) - -# def writeEEPROM(self): -# pass#TODO - - def __turnOn(self): - self.__setFlags() - self.generic.simpleVoltageSetup() - - def __setDataPins(self, value): - self.top.cmdFPGAWrite(0x12, value) - - def __setFlags(self, data_en=0, prog_en=0, ce=1, oe=1): - value = 0 - if data_en: - value |= (1 << 0) - if prog_en: - value |= (1 << 1) - if ce: - value |= (1 << 2) - if oe: - value |= (1 << 3) - self.top.cmdFPGAWrite(0x13, value) - - def __progPulse(self): - self.top.cmdFPGAWrite(0x14, 0) - - def __dataRead(self): - self.top.cmdFPGARead(0x10) - -ChipDescription(Chip_at27c256r, - bitfile = "at27c256r", - runtimeID = (0x000C, 0x01), - chipType = ChipDescription.TYPE_EPROM, - chipVendors = "Atmel", - description = "AT27C256R", - packages = ( ("DIP28", ""), ) -) diff --git a/libtoprammer/chip_at89c2051dip20.py b/libtoprammer/chip_at89c2051dip20.py deleted file mode 100644 index 9a7498e..0000000 --- a/libtoprammer/chip_at89c2051dip20.py +++ /dev/null @@ -1,230 +0,0 @@ -""" -# 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 chip import * - - -class Chip_AT89C2051dip20(Chip): - STAT_BUSY = 0x01 # Programmer is running a command - STAT_ERR = 0x02 # Error during write - - def __init__(self): - Chip.__init__(self, - chipPackage = "DIP20", - chipPinVCC = 20, - chipPinsVPP = 1, - chipPinGND = 10) - - 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.applyGND(True) - self.applyVCC(True) - self.top.cmdSetVPPVoltage(5) - self.__loadCommand(5) # VPP on - self.__loadCommand(1) # set P3.2 - self.__setP3x(P33=0, P34=0, P35=0, IA=0) - data = "" - self.top.cmdFPGARead(0x10) - self.__setP3x(P33=0, P34=0, P35=0, IA=1) - self.__setP3x(P33=0, P34=0, P35=0, IA=0) - self.top.cmdFPGARead(0x10) - self.__setP3x(P33=0, P34=0, P35=0, IA=1) - self.__setP3x(P33=0, P34=0, P35=0, IA=0) - self.top.cmdFPGARead(0x10) - data += self.top.cmdReadBufferReg() - self.__setP3x(P33=0, P34=1, P35=0, IA=0) - 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.applyVPP(True) - self.__loadCommand(5) # VPP on - self.__setP3x(P33=1, P34=0, P35=0, IA=0) - self.top.cmdSetVPPVoltage(12) - self.__runCommandSync(4) - self.applyVPP(False) - self.top.cmdSetVPPVoltage(5) - self.__setP3x(P33=0, P34=1, P35=0, IA=0) - self.__loadCommand(5) # VPP off - self.top.flushCommands() - self.top.printInfo("at89c2051dip20: Erasing flash, verifying ...") - ok = self.__verifyErase() - if ok == 0: - self.top.printInfo("at89c2051dip20: Erase done.") - else: - self.top.printInfo("at89c2051dip20: Erase failed!") - - def readProgmem(self): - self.__initChip() - self.applyGND(True) - self.applyVCC(True) - self.__loadCommand(1) # set P3.2 - self.top.cmdSetVPPVoltage(5) - self.applyVPP(True) - self.__loadCommand(5) # VPP on - self.__setP3x(P33=0, P34=0, P35=1, IA=0) - image = "" - byteCount = 0 - self.progressMeterInit("Reading Flash", 0x800) - for addr in range(0, 0x800): - self.progressMeter(addr) - self.top.cmdFPGARead(0x10) - self.__setP3x(P33=0, P34=0, P35=1, IA=1) - self.__setP3x(P33=0, P34=0, P35=1, IA=0) - byteCount += 1 - if byteCount == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(byteCount) - byteCount = 0 - image += self.top.cmdReadBufferReg(byteCount) - self.applyVPP(False) - self.__setP3x(P33=0, P34=1, P35=0, IA=0) - self.__loadCommand(5) # VPP off - self.top.flushCommands() - self.progressMeterFinish() - - return image - - def writeProgmem(self, image): - if len(image) > 0x800: - self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ - (len(image), 0x800)) - self.__initChip() - self.applyGND(True) - self.applyVCC(True) - self.__loadCommand(1) # set P3.2 - self.top.cmdSetVPPVoltage(5) - self.applyVPP(True) - self.__loadCommand(5) # VPP on - self.__setP3x(P33=0, P34=1, P35=1, IA=0) - 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.__loadCommand(3) - ok = self.__progWait() - if (ok & self.STAT_ERR) != 0: - self.throwError("Write byte failed.") - self.__setP3x(P33=0, P34=1, P35=1, IA=1) - self.__setP3x(P33=0, P34=1, P35=1, IA=0) - self.applyVPP(False) - self.top.cmdSetVPPVoltage(5) - self.__setP3x(P33=0, P34=1, P35=0, IA=0) - self.__loadCommand(5) # VPP off - self.top.flushCommands() - self.progressMeterFinish() - ok = self.__verifyProgmem(image) - if ok == 0: - self.top.printInfo("at89c2051dip20: Write flash done.") - else: - self.top.printInfo("at89c2051dip20: Write flash failed!") - - def __verifyErase(self): - ok = 0 - image = self.readProgmem() - for addr in range(0, 0x800): - if byte2int(image[addr]) != 0xFF: - ok = 1 - return ok - - def __verifyProgmem(self,image): - data = self.readProgmem() - ok = 0 - for addr in range(0, 0x800): - if byte2int(image[addr]) != byte2int(data[addr]): - ok = 1 - return ok - - def __loadData(self, data): - self.top.cmdFPGAWrite(0x10, data) - - def __loadCommand(self, command): - self.top.cmdFPGAWrite(0x12, command & 0xFF) - - def __runCommandSync(self, command): - self.__loadCommand(command) - self.__busyWait() - - def __setP3x(self, P33, P34, P35, IA): - data = 0 - if P33: - data |= 1 - if P34: - data |= 2 - if P35: - data |= 4 - if IA: - data |= 8 - 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.") - -ChipDescription( - Chip_AT89C2051dip20, - bitfile = "at89c2051dip20", - runtimeID = (0x0005, 0x01), - chipVendors = "Atmel", - description = "AT89C2051", - maintainer = None, - packages = ( ("DIP20", ""), ) -) diff --git a/libtoprammer/chip_atmega32dip40.py b/libtoprammer/chip_atmega32dip40.py deleted file mode 100644 index 163459d..0000000 --- a/libtoprammer/chip_atmega32dip40.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel Mega32 DIP40 support -# -# Copyright (c) 2009-2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_atmega_common import * - - -class Chip_ATMega32DIP40(Chip_ATMega_common): - def __init__(self): - Chip_ATMega_common.__init__(self, - chipPackage = "DIP40", - chipPinVCC = 10, - chipPinsVPP = 9, - chipPinGND = 11, - signature = "\x1E\x95\x02", - flashPageSize = 64, - flashPages = 256, - eepromPageSize = 4, - eepromPages = 256) - -ChipDescription( - Chip_ATMega32DIP40, - bitfile = "atmega32dip40", - runtimeID = (0x0004, 0x01), - chipVendors = "Atmel", - description = "AtMega32", - packages = ( ("DIP40", ""), ), - comment = "Insert upside down into ZIF socket" -) diff --git a/libtoprammer/chip_atmega88dip28.py b/libtoprammer/chip_atmega88dip28.py deleted file mode 100644 index 3ea6550..0000000 --- a/libtoprammer/chip_atmega88dip28.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel Mega88 DIP28 support -# -# Copyright (c) 2009-2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_atmega_common import * - - -class Chip_ATMega88DIP28(Chip_ATMega_common): - def __init__(self): - Chip_ATMega_common.__init__(self, - chipPackage = "DIP28", - chipPinVCC = 7, - chipPinsVPP = 1, - chipPinGND = 8, - signature = "\x1E\x93\x0A", - flashPageSize = 32, - flashPages = 128, - eepromPageSize = 4, - eepromPages = 128) - -ChipDescription( - Chip_ATMega88DIP28, - bitfile = "atmega8dip28", - chipID = "atmega88dip28", - runtimeID = (0x0003, 0x01), - chipVendors = "Atmel", - description = "AtMega88", - packages = ( ("DIP28", ""), ), -) diff --git a/libtoprammer/chip_atmega8dip28.py b/libtoprammer/chip_atmega8dip28.py deleted file mode 100644 index 42c6823..0000000 --- a/libtoprammer/chip_atmega8dip28.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel Mega8 DIP28 support -# -# Copyright (c) 2009-2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_atmega_common import * - - -class Chip_ATMega8DIP28(Chip_ATMega_common): - def __init__(self): - Chip_ATMega_common.__init__(self, - chipPackage = "DIP28", - chipPinVCC = 7, - chipPinsVPP = 1, - chipPinGND = 8, - signature = "\x1E\x93\x07", - flashPageSize = 32, - flashPages = 128, - eepromPageSize = 4, - eepromPages = 128) - -fuseDesc = ( - BitDescription(0, "CKSEL0"), - BitDescription(1, "CKSEL1"), - BitDescription(2, "CKSEL2"), - BitDescription(3, "CKSEL3"), - BitDescription(4, "SUT0"), - BitDescription(5, "SUT1"), - BitDescription(6, "BODEN"), - BitDescription(7, "BODLEVEL"), - BitDescription(8, "BOOTRST"), - BitDescription(9, "BOOTSZ0"), - BitDescription(10, "BOOTSZ1"), - BitDescription(11, "EESAVE"), - BitDescription(12, "CKOPT"), - BitDescription(13, "SPIEN"), - BitDescription(14, "WDTON"), - BitDescription(15, "RSTDISBL"), -) - -lockbitDesc = ( - BitDescription(0, "LB1"), - BitDescription(1, "LB2"), - BitDescription(2, "BLB01"), - BitDescription(3, "BLB02"), - BitDescription(4, "BLB11"), - BitDescription(5, "BLB12"), - BitDescription(6, "Unused"), - BitDescription(7, "Unused"), - BitDescription(8, "Unused"), -) - -ChipDescription( - Chip_ATMega8DIP28, - bitfile = "atmega8dip28", - runtimeID = (0x0003, 0x01), - chipVendors = "Atmel", - description = "AtMega8", - fuseDesc = fuseDesc, - lockbitDesc = lockbitDesc, - packages = ( ("DIP28", ""), ) -) diff --git a/libtoprammer/chip_atmega_common.py b/libtoprammer/chip_atmega_common.py deleted file mode 100644 index d507836..0000000 --- a/libtoprammer/chip_atmega_common.py +++ /dev/null @@ -1,465 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Implements the Atmel Mega MCU parallel HV programming algorithm -# -# Copyright (c) 2009-2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_ATMega_common(Chip): - # The Atmel Mega programming commands - CMD_CHIPERASE = 0x80 # Chip Erase - CMD_WRITEFUSE = 0x40 # Write Fuse Bits - CMD_WRITELOCK = 0x20 # Write Lock Bits - CMD_WRITEFLASH = 0x10 # Write Flash - CMD_WRITEEEPROM = 0x11 # Write EEPROM - CMD_READSIG = 0x08 # Read Signature bytes and Calibration byte - CMD_READFUSELOCK = 0x04 # Read Fuse and Lock bits - CMD_READFLASH = 0x02 # Read Flash - CMD_READEEPROM = 0x03 # Read EEPROM - - def __init__(self, - chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, - signature, - flashPageSize, flashPages, - eepromPageSize, eepromPages - ): - 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 - - def readSignature(self): - self.__enterPM() - - (signature, calibration) = self.__readSigAndCalib() - - return signature - - def erase(self): - self.__enterPM() - - self.progressMeterInit("Erasing chip", 0) - self.__loadCommand(self.CMD_CHIPERASE) - self.__pulseWR() - self.__waitForRDY() - self.progressMeterFinish() - - def readProgmem(self): - self.__enterPM() - - self.progressMeterInit("Reading Flash", self.flashPages) - image = "" - for page in range(0, self.flashPages): - self.progressMeter(page) - readWords = 0 - for word in range(0, self.flashPageSize): - self.__loadCommand(self.CMD_READFLASH) - self.__loadAddr((page * self.flashPageSize) + word) - self.__readWordToStatusReg() - readWords += 1 - if readWords >= 32: - image += self.top.cmdReadBufferReg() - readWords = 0 - if readWords: - data = self.top.cmdReadBufferReg() - image += data[0:readWords*2] - self.progressMeterFinish() - return image - - def writeProgmem(self, image): - flashBytes = self.flashPageSize * 2 * self.flashPages - if len(image) != flashBytes: - self.throwError("Invalid program memory image size %d (expected %d)" %\ - (len(image), flashBytes)) - self.__enterPM() - - self.progressMeterInit("Writing Flash", self.flashPages) - for page in range(0, self.flashPages): - self.progressMeter(page) - for word in range(0, self.flashPageSize): - self.__loadCommand(self.CMD_WRITEFLASH) - addr = (page * self.flashPageSize) + word - self.__loadAddr(addr) - addr *= 2 - data = image[addr : addr + 2] - self.__loadData(byte2int(data[0]) | (byte2int(data[1]) << 8)) - self.__setBS1(1) - self.__pulsePAGEL() - self.__setBS1(0) - self.__pulseWR() - self.__waitForRDY() - self.progressMeterFinish() - - def readEEPROM(self): - self.__enterPM() - - assert(self.eepromPageSize <= self.top.getBufferRegSize()) - self.progressMeterInit("Reading EEPROM", self.eepromPages) - image = "" - for page in range(0, self.eepromPages): - self.progressMeter(page) - for byte in range(0, self.eepromPageSize): - self.__loadCommand(self.CMD_READEEPROM) - self.__loadAddr((page * self.eepromPageSize) + byte) - self.__readLowByteToStatusReg() - data = self.top.cmdReadBufferReg() - image += data[0:self.eepromPageSize] - self.progressMeterFinish() - return image - - def writeEEPROM(self, image): - eepromBytes = self.eepromPageSize * self.eepromPages - if len(image) != eepromBytes: - self.throwError("Invalid EEPROM image size %d (expected %d)" %\ - (len(image), eepromBytes)) - self.__enterPM() - - self.progressMeterInit("Writing EEPROM", self.eepromPages) - for page in range(0, self.eepromPages): - self.progressMeter(page) - for byte in range(0, self.eepromPageSize): - self.__loadCommand(self.CMD_WRITEEEPROM) - addr = (page * self.eepromPageSize) + byte - self.__loadAddr(addr) - data = image[addr] - self.__loadDataLow(byte2int(data[0])) - self.__pulsePAGEL() - self.__setBS1(0) - self.__pulseWR() - self.__waitForRDY() - self.progressMeterFinish() - - def readFuse(self): - self.__enterPM() - - self.progressMeterInit("Reading Fuse bits", 0) - (fuse, lock) = self.__readFuseAndLockBits() - self.progressMeterFinish() - return fuse - - def writeFuse(self, image): - if len(image) != 2: - self.throwError("Invalid Fuses image size %d (expected %d)" %\ - (len(image), 2)) - self.__enterPM() - - self.progressMeterInit("Writing Fuse bits", 0) - self.__loadCommand(self.CMD_WRITEFUSE) - self.__setBS2(0) - self.__loadDataLow(byte2int(image[0])) - self.__pulseWR() - self.__waitForRDY() - self.__loadCommand(self.CMD_WRITEFUSE) - self.__loadDataLow(byte2int(image[1])) - self.__setBS1(1) - self.__pulseWR() - self.__waitForRDY() - self.progressMeterFinish() - - def readLockbits(self): - self.__enterPM() - - self.progressMeterInit("Reading lock bits", 0) - (fuses, lockbits) = self.__readFuseAndLockBits() - self.progressMeterFinish() - - return lockbits - - def writeLockbits(self, image): - if len(image) != 1: - self.throwError("Invalid lock-bits image size %d (expected %d)" %\ - (len(image), 1)) - self.__enterPM() - - self.progressMeterInit("Writing lock bits", 0) - self.__loadCommand(self.CMD_WRITELOCK) - self.__loadDataLow(byte2int(image[0])) - self.__pulseWR() - self.__waitForRDY() - self.progressMeterFinish() - - def __readSigAndCalib(self): - """Reads the signature and calibration bytes and returns them. - This function expects a DUT present and pins initialized.""" - signature = "" - calibration = "" - for addr in range(0, 3): - self.__loadCommand(self.CMD_READSIG) - self.__loadAddr(addr) - self.__readWordToStatusReg() - data = self.top.cmdReadBufferReg() - if addr == 0: - calibration += data[1] - signature += data[0] - return (signature, calibration) - - def __readFuseAndLockBits(self): - """Reads the Fuse and Lock bits and returns them. - This function expects a DUT present and pins initialized.""" - self.__loadCommand(self.CMD_READFUSELOCK) - self.__setBS2(0) - self.__readWordToStatusReg() - self.__setBS2(1) - self.__readWordToStatusReg() - self.__setBS2(0) - data = self.top.cmdReadBufferReg() - fuses = data[0] + data[3] - lock = data[1] - return (fuses, lock) - - def __enterPM(self): - "Enter HV programming mode." - self.applyVPP(False) - self.applyVCC(False) - self.applyGND(True) - self.top.cmdSetVPPVoltage(0) - self.top.cmdSetVPPVoltage(12) - self.top.cmdSetVCCVoltage(5) - - self.__setVoltageControl(VPP_en=1, VPP=0, VCC_en=1, VCC=0) - self.__setXA0(0) - self.__setXA1(0) - self.__setBS1(0) - self.__setPAGEL(0) - self.__setWR(0) - self.top.hostDelay(0.1) - - self.applyVCC(True) - self.__setVoltageControl(VPP_en=1, VPP=0, VCC_en=1, VCC=1) - self.top.hostDelay(0.1) - - self.__setOE(0) - self.__setWR(1) - self.__setXTAL1(0) - self.__setXA0(0) - self.__setXA1(0) - self.__setBS1(0) - self.__setBS2(0) - self.__setPAGEL(0) - self.__pulseXTAL1(10) - self.top.flushCommands() - - self.__setVoltageControl(VPP_en=0, VPP=0, VCC_en=1, VCC=1) - self.applyVPP(True) - - self.__setOE(1) - - (signature, calibration) = self.__readSigAndCalib() - 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 __readWordToStatusReg(self): - """Read a data word from the DUT into the status register.""" - self.__setBS1(0) - self.__setOE(0) - self.top.cmdFPGARead(0x10) - self.__setBS1(1) - self.top.cmdFPGARead(0x10) - self.__setOE(1) - - def __readLowByteToStatusReg(self): - """Read the low data byte from the DUT into the status register.""" - self.__setBS1(0) - self.__setOE(0) - self.top.cmdFPGARead(0x10) - self.__setOE(1) - - def __readHighByteToStatusReg(self): - """Read the high data byte from the DUT into the status register.""" - self.__setBS1(1) - self.__setOE(0) - self.top.cmdFPGARead(0x10) - self.__setOE(1) - - def __loadData(self, data): - """Load a data word.""" - self.__loadDataLow(data) - self.__loadDataHigh(data >> 8) - - def __loadDataLow(self, dataLow): - """Load the low data byte.""" - self.__setBS1(0) - self.__setXA0(1) - self.__setXA1(0) - self.top.cmdFPGAWrite(0x10, dataLow & 0xFF) - self.__pulseXTAL1() - - def __loadDataHigh(self, dataHigh): - """Load the high data byte.""" - self.__setBS1(1) - self.__setXA0(1) - self.__setXA1(0) - self.top.cmdFPGAWrite(0x10, dataHigh & 0xFF) - self.__pulseXTAL1() - - def __loadAddr(self, addr): - """Load an address word.""" - self.__loadAddrLow(addr) - self.__loadAddrHigh(addr >> 8) - - def __loadAddrLow(self, addrLow): - """Load the low address byte.""" - self.__setBS1(0) - self.__setXA0(0) - self.__setXA1(0) - self.top.cmdFPGAWrite(0x10, addrLow & 0xFF) - self.__pulseXTAL1() - - def __loadAddrHigh(self, addrHigh): - """Load the high address byte.""" - self.__setBS1(1) - self.__setXA0(0) - self.__setXA1(0) - self.top.cmdFPGAWrite(0x10, addrHigh & 0xFF) - self.__pulseXTAL1() - - def __loadCommand(self, command): - """Load a command into the device.""" -# self.top.queueCommand("\x34") - self.__setBS1(0) -# self.top.queueCommand("\x34") - self.__setXA0(0) - self.__setXA1(1) - self.top.cmdFPGAWrite(0x10, command) - self.__pulseXTAL1() - - def __waitForRDY(self): - """Wait for the RDY pin to go high.""" - self.top.hostDelay(0.01) - for i in range(0, 50): - if self.__getRDY(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout waiting for READY signal from chip.") - - def __getRDY(self): - """Read the state of the RDY/BSY pin.""" - return bool(self.__getStatus() & 0x01) - - def __getStatus(self): - """Read the programmer status register""" - self.top.cmdFPGARead(0x12) - stat = self.top.cmdReadBufferReg() - return byte2int(stat[0]) - - def __setOE(self, high): - """Set the OE pin of the DUT""" - value = 0x02 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __setWR(self, high): - """Set the WR pin of the DUT""" - value = 0x03 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __pulseWR(self, count=1): - """Do a negative pulse on the WR pin of the DUT""" - while count > 0: - self.__setWR(0) - self.__setWR(1) - count -= 1 - - def __setBS1(self, high): - """Set the BS1 pin of the DUT""" - value = 0x04 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __setXA0(self, high): - """Set the XA0 pin of the DUT""" - value = 0x05 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __setXA1(self, high): - """Set the XA1 pin of the DUT""" - value = 0x06 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __setXTAL1(self, high): - """Set the XTAL1 pin of the DUT""" - value = 0x07 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __pulseXTAL1(self, count=1): - """Do a positive pulse on the XTAL1 pin of the DUT""" - while count > 0: - self.__setXTAL1(1) - self.__setXTAL1(0) - count -= 1 - - def __setPAGEL(self, high): - """Set the PAGEL pin of the DUT""" - value = 0x09 - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __pulsePAGEL(self, count=1): - """Do a positive pulse on the PAGEL pin of the DUT""" - while count > 0: - self.__setPAGEL(1) - self.__setPAGEL(0) - count -= 1 - - def __setBS2(self, high): - """Set the BS2 pin of the DUT""" - value = 0x0A - if high: - value |= 0x80 - self.top.cmdFPGAWrite(0x12, value) - - def __setVoltageControl(self, VPP_en, VPP, VCC_en, VCC): - value = 0 - if VPP_en: - value |= 0x01 - if VPP: - value |= 0x02 - if VCC_en: - value |= 0x04 - if VCC: - value |= 0x08 - self.top.cmdFPGAWrite(0x11, value) diff --git a/libtoprammer/chip_attiny13dip8.py b/libtoprammer/chip_attiny13dip8.py deleted file mode 100644 index 9f9a6fe..0000000 --- a/libtoprammer/chip_attiny13dip8.py +++ /dev/null @@ -1,358 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel Tiny13 DIP8 -# -# Copyright (c) 2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_AtTiny13dip8(Chip): - PROGCMD_SENDINSTR = 1 # Send an instruction to the chip - - STAT_BUSY = 0x01 # Programmer is running a command - STAT_SDO = 0x02 # Raw SDO pin state - - def __init__(self): - Chip.__init__(self, - chipPackage = "DIP8", - chipPinVCC = 8, - chipPinsVPP = 1, - chipPinGND = 4) - self.signature = "\x1E\x90\x07" - self.flashPageSize = 16 - self.flashPages = 32 - self.eepromPageSize = 4 - self.eepromPages = 16 - - def readSignature(self): - self.__enterPM() - self.progressMeterInit("Reading signature", 0) - signature = self.__readSignature() - self.progressMeterFinish() - return signature - - def erase(self): - self.__enterPM() - self.progressMeterInit("Erasing chip", 0) - self.__sendInstr(SDI=0x80, SII=0x4C) - self.__sendInstr(SDI=0x00, SII=0x64) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__waitHighSDO() - self.__sendNOP() - self.progressMeterFinish() - - def readProgmem(self): - nrWords = self.flashPages * self.flashPageSize - image = "" - self.__enterPM() - self.progressMeterInit("Reading flash", nrWords) - self.__sendReadFlashInstr() - currentHigh = -1 - bufferedBytes = 0 - for word in range(0, nrWords): - self.progressMeter(word) - low = word & 0xFF - high = (word >> 8) & 0xFF - self.__sendInstr(SDI=low, SII=0x0C) - if high != currentHigh: - self.__sendInstr(SDI=high, SII=0x1C) - currentHigh = high - self.__sendInstr(SDI=0x00, SII=0x68) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__readSDOBufferHigh() - bufferedBytes += 1 - self.__sendInstr(SDI=0x00, SII=0x78) - self.__sendInstr(SDI=0x00, SII=0x7C) - self.__readSDOBufferHigh() - bufferedBytes += 1 - if bufferedBytes == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(bufferedBytes) - 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) - self.__sendWriteFlashInstr() - currentHigh = -1 - for word in range(0, len(image) // 2): - self.progressMeter(word) - low = word & 0xFF - high = (word >> 8) & 0xFF - self.__sendInstr(SDI=low, SII=0x0C) - self.__sendInstr(SDI=byte2int(image[word * 2 + 0]), SII=0x2C) - self.__sendInstr(SDI=byte2int(image[word * 2 + 1]), SII=0x3C) - self.__sendInstr(SDI=0x00, SII=0x7D) - self.__sendInstr(SDI=0x00, SII=0x7C) - if ((word + 1) % self.flashPageSize == 0) or word == len(image) // 2 - 1: - if currentHigh != high: - self.__sendInstr(SDI=high, SII=0x1C) - currentHigh = high - self.__sendInstr(SDI=0x00, SII=0x64) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__waitHighSDO() - self.__sendNOP() - self.progressMeterFinish() - - def readEEPROM(self): - nrBytes = self.eepromPages * self.eepromPageSize - image = "" - self.__enterPM() - self.progressMeterInit("Reading EEPROM", nrBytes) - self.__sendReadEEPROMInstr() - currentPage = -1 - bufferedBytes = 0 - for i in range(0, nrBytes): - self.progressMeter(i) - low = i & 0xFF - high = (i >> 8) & 0xFF - self.__sendInstr(SDI=low, SII=0x0C) - if currentPage != high: - self.__sendInstr(SDI=high, SII=0x1C) - currentPage = high - self.__sendInstr(SDI=0x00, SII=0x68) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__readSDOBufferHigh() - bufferedBytes += 1 - if bufferedBytes == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(bufferedBytes) - bufferedBytes = 0 - image += self.top.cmdReadBufferReg(bufferedBytes) - self.progressMeterFinish() - return image - - def writeEEPROM(self, image): - nrBytes = self.eepromPages * self.eepromPageSize - if len(image) > nrBytes: - self.throwError("Invalid EEPROM image size %d (expected <=%d)" %\ - (len(image), nrBytes)) - self.__enterPM() - self.progressMeterInit("Writing EEPROM", len(image)) - self.__sendWriteEEPROMInstr() - for i in range(0, len(image)): - self.progressMeter(i) - self.__sendInstr(SDI=i, SII=0x0C) - self.__sendInstr(SDI=byte2int(image[i]), SII=0x2C) - self.__sendInstr(SDI=0x00, SII=0x6D) - self.__sendInstr(SDI=0x00, SII=0x6C) - if ((i + 1) % self.eepromPageSize == 0) or i == len(image) - 1: - self.__sendInstr(SDI=0x00, SII=0x64) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__waitHighSDO() - self.__sendNOP() - self.progressMeterFinish() - - def readFuse(self): - fuses = [] - self.__enterPM() - self.progressMeterInit("Reading fuses", 0) - self.__sendInstr(SDI=0x04, SII=0x4C) - self.__sendInstr(SDI=0x00, SII=0x68) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__readSDOBufferHigh() - fuses.append(self.top.cmdReadBufferReg(1)) - self.__sendInstr(SDI=0x04, SII=0x4C) - self.__sendInstr(SDI=0x00, SII=0x7A) - self.__sendInstr(SDI=0x00, SII=0x7E) - self.__readSDOBufferHigh() - fuses.append(int2byte(self.top.cmdReadBufferReg8() | 0xE0)) - self.progressMeterFinish() - return b"".join(fuses) - - def writeFuse(self, image): - if len(image) != 2: - self.throwError("Invalid Fuses image size %d (expected %d)" %\ - (len(image), 2)) - self.__enterPM() - self.progressMeterInit("Writing fuses", 0) - self.__sendInstr(SDI=0x40, SII=0x4C) - self.__sendInstr(SDI=byte2int(image[0]), SII=0x2C) - self.__sendInstr(SDI=0x00, SII=0x64) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__waitHighSDO() - self.__sendInstr(SDI=0x40, SII=0x4C) - self.__sendInstr(SDI=(byte2int(image[1]) & 0x1F), SII=0x2C) - self.__sendInstr(SDI=0x00, SII=0x74) - self.__sendInstr(SDI=0x00, SII=0x7C) - self.__waitHighSDO() - self.progressMeterFinish() - - def readLockbits(self): - self.__enterPM() - self.progressMeterInit("Reading lockbits", 0) - self.__sendInstr(SDI=0x04, SII=0x4C) - self.__sendInstr(SDI=0x00, SII=0x78) - self.__sendInstr(SDI=0x00, SII=0x7C) - self.__readSDOBufferHigh() - lockbits = int2byte(self.top.cmdReadBufferReg8() | 0xFC) - self.progressMeterFinish() - return lockbits - - def writeLockbits(self, image): - if len(image) != 1: - self.throwError("Invalid Lockbits image size %d (expected %d)" %\ - (len(image), 1)) - self.__enterPM() - self.progressMeterInit("Writing lockbits", 0) - self.__sendInstr(SDI=0x20, SII=0x4C) - self.__sendInstr(SDI=(byte2int(image[0]) & 3), SII=0x2C) - self.__sendInstr(SDI=0x00, SII=0x64) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__waitHighSDO() - self.progressMeterFinish() - - def __readSignature(self): - self.__sendInstr(SDI=0x08, SII=0x4C) - for i in range(0, 3): - self.__sendInstr(SDI=i, SII=0x0C) - self.__sendInstr(SDI=0x00, SII=0x68) - self.__sendInstr(SDI=0x00, SII=0x6C) - self.__readSDOBufferHigh() - return self.top.cmdReadBufferReg()[0:3] - - def __enterPM(self): - "Enter HV programming mode." - self.applyVCC(False) - self.applyVPP(False) - self.applyGND(False) - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(0) - self.top.cmdSetVPPVoltage(12) - self.applyGND(True) - self.applyVCC(True) - - self.__setPins(SCI=0, SDO_en=0, RST_en=1, RST=0) - for i in range(0, 6): - self.__setPins(SCI=0, SDO_en=0, RST_en=1, RST=0) - self.__setPins(SCI=1, SDO_en=0, RST_en=1, RST=0) - self.__setPins(SCI=0, SDO_en=1, SDO=0, RST_en=1, RST=0) - self.top.hostDelay(0.001) - self.__setPins(SDO_en=1, SDO=0, RST_en=0) - self.applyVPP(True) - self.top.hostDelay(0.001) - self.__setPins(SDO_en=0) - self.top.hostDelay(0.01) - - 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 __sendReadEEPROMInstr(self): - self.__sendInstr(SDI=0x03, SII=0x4C) - - def __sendWriteEEPROMInstr(self): - self.__sendInstr(SDI=0x11, SII=0x4C) - - def __sendReadFlashInstr(self): - self.__sendInstr(SDI=0x02, SII=0x4C) - - def __sendWriteFlashInstr(self): - self.__sendInstr(SDI=0x10, SII=0x4C) - - def __sendNOP(self): - self.__sendInstr(SDI=0x00, SII=0x4C) - - def __sendInstr(self, SDI, SII): - self.__setSDI(SDI) - self.__setSII(SII) - 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) - - def __setSDI(self, sdi): - self.top.cmdFPGAWrite(0x13, sdi & 0xFF) - - def __setSII(self, sii): - self.top.cmdFPGAWrite(0x14, sii & 0xFF) - - def __loadCommand(self, command): - self.top.cmdFPGAWrite(0x12, command & 0xFF) - - def __runCommandSync(self, command): - self.__loadCommand(command) - self.__busyWait() - - def __setPins(self, SCI=0, SDO_en=0, SDO=0, RST_en=0, RST=0): - data = 0 - if SCI: - data |= 1 - if SDO_en: - data |= 2 - if SDO: - data |= 4 - if RST_en: - data |= 8 - if RST: - data |= 16 - 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 __rawSDOState(self): - return bool(self.__getStatusFlags() & self.STAT_SDO) - - 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 __waitHighSDO(self): - for i in range(0, 100): - if self.__rawSDOState(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout waiting for SDO.") - -ChipDescription( - Chip_AtTiny13dip8, - bitfile = "attiny13dip8", - runtimeID = (0x0001, 0x01), - chipVendors = "Atmel", - description = "AtTiny13", - packages = ( ("DIP8", ""), ), -) diff --git a/libtoprammer/chip_attiny26dip20.py b/libtoprammer/chip_attiny26dip20.py deleted file mode 100644 index 213f7b6..0000000 --- a/libtoprammer/chip_attiny26dip20.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Atmel Tiny26 DIP20 support -# -# Copyright (c) 2009-2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_atmega_common import * - - -class Chip_ATTiny26DIP20(Chip_ATMega_common): - def __init__(self): - Chip_ATMega_common.__init__(self, - chipPackage = "DIP20", - chipPinVCC = 5, - chipPinsVPP = 10, - chipPinGND = 6, - signature = "\x1E\x91\x09", - flashPageSize = 16, - flashPages = 64, - eepromPageSize = 4, - eepromPages = 32) - -ChipDescription( - Chip_ATTiny26DIP20, - bitfile = "attiny26dip20", - runtimeID = (0x0002, 0x01), - chipVendors = "Atmel", - description = "AtTiny26", - packages = ( ("DIP20", ""), ), - comment = "Special ZIF position", - broken = True -) diff --git a/libtoprammer/chip_generic_sram.py b/libtoprammer/chip_generic_sram.py deleted file mode 100644 index 972931b..0000000 --- a/libtoprammer/chip_generic_sram.py +++ /dev/null @@ -1,122 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Generic SRAM chip -# -# Copyright (c) 2011 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_genericSRAM(Chip): - def __init__(self, chipPackage, chipPinVCC, chipPinGND, - VCCVoltage, - nrAddressBits, nrDataBits): - Chip.__init__(self, - chipPackage = chipPackage, - chipPinVCC = chipPinVCC, - chipPinGND = chipPinGND) - self.VCCVoltage = VCCVoltage - self.nrAddressBits = nrAddressBits - self.nrAddressBytes = int(math.ceil((float(self.nrAddressBits) - 0.1) / 8)) - self.nrDataBits = nrDataBits - assert(nrDataBits == 8) - - def erase(self): - self.writeRAM(int2byte(0) * self.__sizeBytes()) - - def test(self): - generic = GenericAlgorithms(self) - generic.simpleTest(self.readRAM, self.writeRAM, - self.__sizeBytes()) - - def readRAM(self): - image = [] - - self.progressMeterInit("Reading SRAM", self.__sizeBytes()) - self.__turnOnChip() - self.__setControlPins(CE=0, OE=0, WE=1) - nrBytes = 0 - for addr in range(0, self.__sizeBytes()): - self.progressMeter(addr) - self.__setAddress(addr) - self.__readData() - nrBytes += 1 - if nrBytes == self.top.getBufferRegSize(): - image.append(self.top.cmdReadBufferReg(nrBytes)) - nrBytes = 0 - image.append(self.top.cmdReadBufferReg(nrBytes)) - self.__setControlPins(CE=1, OE=1, WE=1) - self.progressMeterFinish() - - return b"".join(image) - - def writeRAM(self, image): - if len(image) > self.__sizeBytes(): - self.throwError("Invalid memory image size %d (expected max %d)" %\ - (len(image), self.__sizeBytes())) - - self.progressMeterInit("Writing SRAM", self.__sizeBytes()) - self.__turnOnChip() - self.__setControlPins(CE=0, OE=1, WE=1) - for addr in range(0, len(image)): - self.progressMeter(addr) - self.__setAddress(addr) - self.__writeData(image[addr]) - self.__setControlPins(CE=0, OE=1, WE=0) - self.top.cmdDelay(0.00000007) # Delay at least 70 nsec - self.__setControlPins(CE=0, OE=1, WE=1) - self.__setControlPins(CE=1, OE=1, WE=1) - self.progressMeterFinish() - - def __sizeBytes(self): - return (1 << self.nrAddressBits) - - def __turnOnChip(self): - self.__setControlPins(CE=1, OE=1, WE=1) - self.top.cmdSetVCCVoltage(self.VCCVoltage) - self.applyGND(True) - self.applyVCC(True) - self.lastAddress = None - - def __setControlPins(self, CE=1, OE=1, WE=1): - value = 0 - if CE: - value |= 1 - if OE: - value |= 2 - if WE: - value |= 4 - self.top.cmdFPGAWrite(0x11, value) - - def __writeData(self, data): - data = byte2int(data) - self.top.cmdFPGAWrite(0x10, data) - - def __readData(self): - self.top.cmdFPGARead(0x10) - - def __setAddress(self, addr): - for i in range(0, self.nrAddressBytes): - shift = 8 * i - mask = 0xFF << shift - if self.lastAddress is None or\ - (self.lastAddress & mask) != (addr & mask): - self.top.cmdFPGAWrite(0x12 + i, - (addr & mask) >> shift) - self.lastAddress = addr diff --git a/libtoprammer/chip_hm62256dip28.py b/libtoprammer/chip_hm62256dip28.py deleted file mode 100644 index cf3a40a..0000000 --- a/libtoprammer/chip_hm62256dip28.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# HM62256 DIP28 SRAM support -# -# Copyright (c) 2011 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip_generic_sram import * - - -class Chip_HM62256DIP28(Chip_genericSRAM): - def __init__(self): - Chip_genericSRAM.__init__(self, - chipPackage = "DIP28", - chipPinVCC = 28, - chipPinGND = 14, - VCCVoltage = 5, - nrAddressBits = 15, - nrDataBits = 8, - ) - -ChipDescription( - Chip_HM62256DIP28, - bitfile = "hm62256dip28", - runtimeID = (0x000A, 0x01), - chipType = ChipDescription.TYPE_SRAM, - chipVendors = "S@Tech", - description = "HM62256 SRAM", - packages = ( ("DIP28", ""), ) -) diff --git a/libtoprammer/chip_m24cxxdip8.py b/libtoprammer/chip_m24cxxdip8.py deleted file mode 100644 index bc40748..0000000 --- a/libtoprammer/chip_m24cxxdip8.py +++ /dev/null @@ -1,260 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# M24C16 I2C based serial EEPROM -# -# Copyright (c) 2011 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_m24cXXdip8_common(Chip): - CMD_DEVSEL_READ = 0 - CMD_DEVSEL_WRITE = 1 - CMD_SETADDR = 2 - CMD_DATA_READ = 3 - CMD_DATA_READ_STOP = 4 - CMD_DATA_WRITE = 5 - CMD_DATA_WRITE_STOP = 6 - - def __init__(self, eepromSize): - Chip.__init__(self, - chipPackage = "DIP8", - chipPinVCC = 8, - chipPinGND = 4) - self.eepromSize = eepromSize # in bytes - - def __chipTurnOn(self): - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(5) - self.applyVCC(True) - self.applyVPP(False) - self.applyGND(True) - self.top.cmdEnableZifPullups(True) - - self.currentAddrExt = None - - def erase(self): - self.writeEEPROM("\xFF" * self.eepromSize) - - def readEEPROM(self): - self.__chipTurnOn() - - image = "" - count = 0 - prevAddr = None - self.progressMeterInit("Reading EEPROM", self.eepromSize) - for addr in range(0, self.eepromSize): - self.progressMeter(addr) - if prevAddr is None or (prevAddr & 0xFF00) != (addr & 0xFF00): - self.__setAddress(addr, writeMode=False) - self.__runCommand(self.CMD_DEVSEL_WRITE) - self.__runCommand(self.CMD_SETADDR) - self.__runCommand(self.CMD_DEVSEL_READ) - self.__runCommand(self.CMD_DATA_READ_STOP) - prevAddr = addr - else: - self.__runCommand(self.CMD_DEVSEL_READ) - self.__runCommand(self.CMD_DATA_READ_STOP) - self.__readData() - count += 1 - if count == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(count) - count = 0 - image += self.top.cmdReadBufferReg(count) - self.progressMeterFinish() - - return image - - def writeEEPROM(self, image): - if len(image) > self.eepromSize: - self.throwError("Invalid EEPROM image size %d (expected <=%d)" %\ - (len(image), self.eepromSize)) - self.__chipTurnOn() - - self.progressMeterInit("Writing EEPROM", len(image)) - prevAddr = None - for addr in range(0, len(image)): - self.progressMeter(addr) - self.__setData(byte2int(image[addr])) - if prevAddr is None or (prevAddr & 0xFFF0) != (addr & 0xFFF0): - self.__setAddress(addr, writeMode=True) - self.__runCommand(self.CMD_DEVSEL_WRITE, busyWait=True) - self.__runCommand(self.CMD_SETADDR, busyWait=True) - self.__runCommand(self.CMD_DATA_WRITE, busyWait=True) - prevAddr = addr - else: - if (addr & 0xF) == 0xF: - self.__runCommand(self.CMD_DATA_WRITE_STOP, busyWait=True) - else: - self.__runCommand(self.CMD_DATA_WRITE, busyWait=True) - self.progressMeterFinish() - - def __readData(self): - self.top.cmdFPGARead(0x10) - - def __setData(self, dataByte): - self.top.cmdFPGAWrite(0x12, dataByte & 0xFF) - - def __setAddress(self, address, writeMode): - # Address base - self.top.cmdFPGAWrite(0x11, address & 0xFF) - # Address extension - sizeMask = self.eepromSize - 1 - assert(sizeMask & ~0x7FF == 0) - addrExt = address & 0x700 & sizeMask - if self.currentAddrExt != addrExt: - self.currentAddrExt = addrExt - if sizeMask & 0x0100: - E0 = addrExt & 0x0100 - E0_en = 0 - else: - E0 = 0 - E0_en = 1 - if sizeMask & 0x0200: - E1 = addrExt & 0x0200 - E1_en = 0 - else: - E1 = 0 - E1_en = 1 - if sizeMask & 0x0400: - E2 = addrExt & 0x0400 - E2_en = 0 - else: - E2 = 0 - E2_en = 1 - if writeMode: - WC = 0 - else: - WC = 1 - self.__setControlPins(E0=E0, E0_en=E0_en, - E1=E1, E1_en=E1_en, - E2=E2, E2_en=E2_en, - WC=WC) - - def __runCommand(self, command, busyWait=False): - self.top.cmdFPGAWrite(0x10, command & 0xFF) - if busyWait: - self.__busyWait() - else: - # We do not read busy flags, but wait long enough for - # the operation to finish. This is safe for eeprom read. - self.top.cmdDelay(0.00009) - - def __isBusy(self): - (busy0, busy1) = self.__getStatusFlags() - return busy0 != busy1 - - def __busyWait(self): - for i in range(0, 100): - if not self.__isBusy(): - return - self.top.hostDelay(0.001) - self.throwError("Timeout in busywait.") - - def __getStatusFlags(self): - self.top.cmdFPGARead(0x11) - stat = self.top.cmdReadBufferReg8() - busy0 = bool(stat & 0x01) - busy1 = bool(stat & 0x02) - return (busy0, busy1) - - def __setControlPins(self, E0, E0_en, E1, E1_en, E2, E2_en, WC): - value = 0 - if E0: - value |= (1 << 0) - if E0_en: - value |= (1 << 1) - if E1: - value |= (1 << 2) - if E1_en: - value |= (1 << 3) - if E2: - value |= (1 << 4) - if E2_en: - value |= (1 << 5) - if WC: - value |= (1 << 6) - self.top.cmdFPGAWrite(0x13, value) - -class Chip_m24c01dip8(Chip_m24cXXdip8_common): - def __init__(self): - Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 1 // 8) - -class Chip_m24c02dip8(Chip_m24cXXdip8_common): - def __init__(self): - Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 2 // 8) - -class Chip_m24c04dip8(Chip_m24cXXdip8_common): - def __init__(self): - Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 4 // 8) - -class Chip_m24c08dip8(Chip_m24cXXdip8_common): - def __init__(self): - Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 8 // 8) - -class Chip_m24c16dip8(Chip_m24cXXdip8_common): - def __init__(self): - Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 16 // 8) - -class ChipDescription_m24cXX(ChipDescription): - def __init__(self, chipImplClass, chipID, description): - ChipDescription.__init__(self, - chipImplClass = chipImplClass, - bitfile = "m24c16dip8", - chipID = chipID, - runtimeID = (0x000B, 0x01), - chipType = ChipDescription.TYPE_EEPROM, - chipVendors = "ST", - description = description, - packages = ( - ("DIP8", ""), - ("SO8", "With 1:1 adapter"), - ("TSSOP8", "With 1:1 adapter"), - ), - ) - -ChipDescription_m24cXX( - Chip_m24c01dip8, - chipID = "m24c01dip8", - description = "M24C01 I2C EEPROM", -) - -ChipDescription_m24cXX( - Chip_m24c02dip8, - chipID = "m24c02dip8", - description = "M24C02 I2C EEPROM", -) - -ChipDescription_m24cXX( - Chip_m24c04dip8, - chipID = "m24c04dip8", - description = "M24C04 I2C EEPROM", -) - -ChipDescription_m24cXX( - Chip_m24c08dip8, - chipID = "m24c08dip8", - description = "M24C08 I2C EEPROM", -) - -ChipDescription_m24cXX( - Chip_m24c16dip8, - chipID = "m24c16dip8", - description = "M24C16 I2C EEPROM", -) diff --git a/libtoprammer/chip_m2764a.py b/libtoprammer/chip_m2764a.py deleted file mode 100644 index a0f9921..0000000 --- a/libtoprammer/chip_m2764a.py +++ /dev/null @@ -1,173 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# M2764A EPROM programmer -# -# Copyright (c) 2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_M2764A(Chip): - PROGCMD_PPULSE = 1 # Perform a P-pulse - - STAT_BUSY = 0x01 # Programmer is running a command - - def __init__(self): - Chip.__init__(self, - chipPackage = "DIP28", - chipPinVCC = 28, - chipPinsVPP = 1, - chipPinGND = 14) - - def __initChip(self): - self.applyVCC(False) - self.applyVPP(False) - self.applyGND(False) - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(0) - self.top.cmdSetVPPVoltage(5) - - def readEEPROM(self): - self.__initChip() - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(5) - self.applyVCC(True) - self.applyVPP(True) - self.applyGND(True) - - image = "" - self.progressMeterInit("Reading EPROM", 0x2000) - self.__setEG(E=1, G=1) - byteCount = 0 - for addr in range(0, 0x2000): - self.progressMeter(addr) - self.__readDataToStatusReg(addr) - byteCount += 1 - if byteCount == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(byteCount) - byteCount = 0 - image += self.top.cmdReadBufferReg(byteCount) - self.__setEG(E=1, G=1) - self.progressMeterFinish() - - return image - - def writeEEPROM(self, image): - if len(image) > 0x2000: - self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ - (len(image), 0x2000)) - - self.__initChip() - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(12) - self.applyVCC(True) - self.applyVPP(True) - self.applyGND(True) - - self.progressMeterInit("Writing EPROM", len(image)) - self.__setEG(E=1, G=1) - for addr in range(0, len(image)): - self.progressMeter(addr) - data = byte2int(image[addr]) - if data != 0xFF: - self.__writeData(addr, data) - self.__setEG(E=1, G=1) - self.progressMeterFinish() - - def __readDataToStatusReg(self, addr): - self.__loadAddr(addr) - self.__setEG(E=0, G=0) - self.top.cmdFPGARead(0x10) - - def __writeData(self, addr, data): - self.__setEG(E=0, G=1) - self.__loadAddr(addr) - self.__loadData(data) - self.__loadPPulseLen(1) - self.__runCommandSync(self.PROGCMD_PPULSE) - for i in range(0, 25): - self.__readDataToStatusReg(addr) - stat = self.top.cmdReadBufferReg() - r = byte2int(stat[0]) - if r == data: - break - self.__setEG(E=0, G=1) - self.__runCommandSync(self.PROGCMD_PPULSE) - else: - self.throwError("Failed to program 0x%04X (got 0x%02X, expected 0x%02X)" %\ - (addr, r, data)) - self.__setEG(E=0, G=1) - self.__loadPPulseLen(3 * (i + 1)) - self.__runCommandSync(self.PROGCMD_PPULSE) - - def __loadData(self, data): - self.top.cmdFPGAWrite(0x10, data) - - def __loadCommand(self, command): - self.top.cmdFPGAWrite(0x12, command & 0xFF) - - def __runCommandSync(self, command): - self.__loadCommand(command) - self.__busyWait() - - def __loadAddrLow(self, addrLow): - self.top.cmdFPGAWrite(0x13, addrLow & 0xFF) - - def __loadAddrHigh(self, addrHigh): - self.top.cmdFPGAWrite(0x14, addrHigh & 0xFF) - - def __loadAddr(self, addr): - self.__loadAddrLow(addr) - self.__loadAddrHigh(addr >> 8) - - def __loadPPulseLen(self, msec): - self.top.cmdFPGAWrite(0x15, msec) - - def __setEG(self, E, G): - data = 0 - if E: - data |= 1 - if G: - data |= 2 - self.top.cmdFPGAWrite(0x16, data) - - def __getStatusFlags(self): - self.top.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, 100): - if not self.__busy(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout in busywait.") - -ChipDescription( - Chip_M2764A, - bitfile = "m2764a", - runtimeID = (0x0006, 0x01), - chipType = ChipDescription.TYPE_EPROM, - description = "M2764A EPROM", - maintainer = None, - packages = ( ("DIP28", ""), ), -) diff --git a/libtoprammer/chip_m8cissp.py b/libtoprammer/chip_m8cissp.py deleted file mode 100644 index ff85e5e..0000000 --- a/libtoprammer/chip_m8cissp.py +++ /dev/null @@ -1,457 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Cypress M8C In System Serial Programmer -# -# Copyright (c) 2010-2011 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * -import time - - -class Chip_M8C_ISSP(Chip): - ISSPCMD_POR = 1 # Perform a power-on-reset - ISSPCMD_PWROFF = 2 # Turn power off - ISSPCMD_EXEC = 3 # Do an "execute" transfer - - STAT_BUSY0 = 0x01 - STAT_BUSY1 = 0x02 - STAT_ISSPSTATE = 0x1C - STAT_ISSPSTATE_SHIFT = 2 - STAT_SDATA = 0x20 - - STRVEC_INIT1 = ( - "1100101010000000000111", - "0000000000000000000000", - "0000000000000000000000", - "0000000000000000000000", - "0000000000000000000000", - "0000000000000000000000", - "1101111011100010000111", - "1101111101000000000111", - "1101111011100000000111", - "1101111011100010000111", - "1101111111000000100111", - "1101110001000000100111", - "1101110000000000011111", - "1101111011100000000111", - "1001111100000111010111", - "1001111100100000011111", - "1001111101101000000111", - "1001111110000000000111", - "1001111111001010110111", - "1001111110100000001111", - "1001111111100000001111", - "1001111111110000000111", - "1101111011100010000111", - "1101110001000000000111", - "1101111111000000000111", - "1101110000000000000111", - "1101111011100000000111", - "1101111010000000011111", - "1101111010100000000111", - "1101111011000000000111", - "1101111100000000000111", - "1101111100100110000111", - ) - - STRVEC_INIT2 = ( - "1001111101000000000111", - "1101111000000000110111", - "1101111100000000000111", - "1101111111100010010111", - ) - - STRVEC_IDSETUP = ( - "1101111011100010000111", - "1101110000000000010111", - "1101111011100010000111", - "1101111101000000000111", - "1101111011100000000111", - "1101111011100010000111", - "1101111111000000100111", - "1101110001000000100111", - "1101110000000000011111", - "1101111011100000000111", - "1001111100000111010111", - "1001111100100000011111", - "1001111101101000000111", - "1001111110000000000111", - "1001111111001010110111", - "1001111110100000001111", - "1001111111100000001111", - "1001111111110000000111", - "1101111011100010000111", - "1101110001000000000111", - "1101111111000000000111", - "1101110000000000000111", - "1101111011100000000111", - "1101111010000000011111", - "1101111010100000000111", - "1101111011000000000111", - "1101111100000000000111", - "1101111100100110000111", - "1001111101000000000111", - "1101111000000000110111", - "1101111100000000000111", - "1101111111100010010111", - ) - - STRVEC_READBYTE = ( - "101aaaaaaaaZDDDDDDDDZ1", - ) - - STRVEC_WRITEBYTE = ( - "100aaaaaaaadddddddd111", - ) - - STRVEC_ERASEALL = ( - "1001111110000010101111", - "1001111111001010110111", - "1101111011100010000111", - "1101111101000000000111", - "1101111011100000000111", - "1101111011100010000111", - "1101111111000000100111", - "1101110001000000100111", - "1101110000000000011111", - "1101111011100000000111", - "1001111100000111010111", - "1001111100100000011111", - "1001111101101000000111", - "1001111110000000000111", - "1001111111001010110111", - "1001111110100000001111", - "1001111111100000001111", - "1001111111110000000111", - "1101111011100010000111", - "1101110001000000000111", - "1101111111000000000111", - "1101110000000000000111", - "1101111011100000000111", - "1101111010000000011111", - "1101111010100000000111", - "1101111011000000000111", - "1101111100000000000111", - "1101111100100110000111", - "1101111000000000101111", - "1101111100000000000111", - "1101111111100010010111", - ) - - STRVEC_SETBLKNUM = ( - "10011111010dddddddd111", - ) - - STRVEC_READBLK = ( - "1101111011100010000111", - "1101111101000000000111", - "1101111011100000000111", - "1101111011100010000111", - "1101111111000000100111", - "1101110001000000100111", - "1101110000000000011111", - "1101111011100000000111", - "1001111100000111010111", - "1001111100100000011111", - "1001111101101000000111", - "1001111110000000000111", - "1001111111001010110111", - "1001111110100000001111", - "1001111111100000001111", - "1001111111110000000111", - "1101111011100010000111", - "1101110001000000000111", - "1101111111000000000111", - "1101110000000000000111", - "1101111011100000000111", - "1101111010000000011111", - "1101111010100000000111", - "1101111011000000000111", - "1101111100000000000111", - "1101111100100110000111", - "1101111000000000001111", - "1101111100000000000111", - "1101111111100010010111", - ) - - STRVEC_WRITEBLK = ( - "1001111110001010100111", - "1001111111001010110111", - "1101111011100010000111", - "1101111101000000000111", - "1101111011100000000111", - "1101111011100010000111", - "1101111111000000100111", - "1101110001000000100111", - "1101110000000000011111", - "1101111011100000000111", - "1001111100000111010111", - "1001111100100000011111", - "1001111101101000000111", - "1001111110000000000111", - "1001111111001010110111", - "1001111110100000001111", - "1001111111100000001111", - "1001111111110000000111", - "1101111011100010000111", - "1101110001000000000111", - "1101111111000000000111", - "1101110000000000000111", - "1101111011100000000111", - "1101111010000000011111", - "1101111010100000000111", - "1101111011000000000111", - "1101111100000000000111", - "1101111100100110000111", - "1101111000000000010111", - "1101111100000000000111", - "1101111111100010010111", - ) - - STRVEC_READCHKSUM = ( - "10111111001ZDDDDDDDDZ1", - "10111111000ZDDDDDDDDZ1", - ) - - STRVEC_READID = ( - "10111111000ZDDDDDDDDZ1", - "10111111001ZDDDDDDDDZ1", - ) - - def __init__(self): - Chip.__init__(self) -# self.progmemSize = 1024 * 16 - self.progmemSize = 256#XXX - - def readSignature(self): - self.progressMeterInit("Reading chip ID", 0) - self.__powerOnReset() - gotID = self.__readID() - self.progressMeterFinish() - - return int2byte(gotID & 0xFF) + int2byte((gotID >> 8) & 0xFF) - - def erase(self): - self.progressMeterInit("Erasing chip", 0) - self.__powerOnReset() - self.__bitbangStringVectors(self.STRVEC_ERASEALL) - self.__runCommandSync(self.ISSPCMD_EXEC) - self.progressMeterFinish() - - def writeProgmem(self, image): - if len(image) > self.progmemSize or len(image) % 64 != 0: - self.throwError("Invalid program memory image size %d " - "(expected <=%d and multiple of 64)" %\ - (len(image), self.progmemSize)) - - self.progressMeterInit("Writing program memory", len(image)) - self.__powerOnReset() - for blknum in range(0, len(image) // 64): - for i in range(0, 64): - self.progressMeter(blknum * 64 + i) - self.__writeByte(i, byte2int(image[blknum * 64 + i])) - vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum) - self.__bitbangStringVector(vec) - self.__bitbangStringVectors(self.STRVEC_WRITEBLK) - self.__runCommandSync(self.ISSPCMD_EXEC) - self.progressMeterFinish() - - def readProgmem(self): - self.progressMeterInit("Reading program memory", self.progmemSize) - self.__powerOnReset() - assert(self.progmemSize % 64 == 0) - image = [] - for blknum in range(0, self.progmemSize // 64): - vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum) - self.__bitbangStringVector(vec) - self.__bitbangStringVectors(self.STRVEC_READBLK) - self.__runCommandSync(self.ISSPCMD_EXEC) - for i in range(0, 64): - self.progressMeter(blknum * 64 + i) - image.append(int2byte(self.__readByte(i))) - #FIXME return_code - self.progressMeterFinish() - return b"".join(image) - - def __powerDown(self): - "Turn the power to the device off" - self.printDebug("Powering device down...") - self.__runCommandSync(self.ISSPCMD_PWROFF) - self.top.hostDelay(5) - - def __powerOnReset(self): - "Perform a complete power-on-reset and initialization" - self.top.vcc.setLayoutMask(0) - self.top.vpp.setLayoutMask(0) - self.top.gnd.setLayoutMask(0) - self.top.cmdSetVCCVoltage(5) - self.top.cmdSetVPPVoltage(5) - - self.printDebug("Initializing supply power...") - self.top.gnd.setLayoutPins( (20,) ) - self.top.vcc.setLayoutPins( (21,) ) - -#FIXME when to do exec? - self.__powerDown() - self.printDebug("Performing a power-on-reset...") - self.__uploadStringVector(self.STRVEC_INIT1[0]) - self.__runCommandSync(self.ISSPCMD_POR) - self.printDebug("Sending vector 1...") - self.__bitbangStringVectors(self.STRVEC_INIT1[1:]) -#XXX self.__runCommandSync(self.ISSPCMD_EXEC) - self.printDebug("Sending vector 2...") - self.__bitbangStringVectors(self.STRVEC_INIT2) - self.__runCommandSync(self.ISSPCMD_EXEC) - - def __readID(self): - "Read the silicon ID" - self.__bitbangStringVectors(self.STRVEC_IDSETUP) - self.__runCommandSync(self.ISSPCMD_EXEC) - - low = (self.__bitbangStringVector(self.STRVEC_READID[0]) >> 2) & 0xFF - high = (self.__bitbangStringVector(self.STRVEC_READID[1]) >> 2) & 0xFF - - return low | (high << 8) - - def __readByte(self, address): - vec = self.__stringVectorReplace(self.STRVEC_READBYTE[0], "a", address) - inputData = self.__bitbangStringVector(vec) - return (inputData >> 2) & 0xFF - - def __writeByte(self, address, byte): - vec = self.__stringVectorReplace(self.STRVEC_WRITEBYTE[0], "a", address) - vec = self.__stringVectorReplace(vec, "d", byte) - self.__bitbangStringVector(vec) - - def __loadCommand(self, command): - self.top.cmdFPGAWrite(0x11, command & 0xFF) - - def __runCommandSync(self, command): - self.printDebug("Running synchronous command %d" % command) - self.__loadCommand(command) - self.__busyWait() - - def __setBitbang(self, SDATA, SDATA_in, SCLK, SCLK_z): - value = 0 - if SDATA: - value |= 0x01 - if SDATA_in: - value |= 0x02 - if SCLK: - value |= 0x04 - if SCLK_z: - value |= 0x08 - self.top.cmdFPGAWrite(0x10, value) - - def __getStatusFlags(self): - self.top.cmdFPGARead(0x10) - stat = self.top.cmdReadBufferReg8() - isspState = (stat & self.STAT_ISSPSTATE) >> self.STAT_ISSPSTATE_SHIFT - sdata = bool(stat & self.STAT_SDATA) - isBusy = bool(stat & self.STAT_BUSY0) != bool(stat & self.STAT_BUSY1) - self.printDebug("isspState = 0x%02X, isBusy = %d, busyFlags = 0x%01X, sdata = %d" %\ - (isspState, isBusy, (stat & (self.STAT_BUSY0 | self.STAT_BUSY1)), sdata)) - return (isBusy, sdata, isspState) - - def __busy(self): - (isBusy, sdata, isspState) = self.__getStatusFlags() - return isBusy - - def __getSDATA(self): - (isBusy, sdata, isspState) = self.__getStatusFlags() - return int(sdata) - - def __busyWait(self): - for i in range(0, 200): - if not self.__busy(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout in busywait. Chip not responding?") - - def __stringVectorToBinary(self, vector): - binary = 0 - inputMask = 0 - assert(len(vector) == 22) - bit = len(vector) - 1 - for b in vector: - if b == "1": - binary |= (1 << bit) - elif b == "0": - pass - elif b == "H" or b == "L" or b == "Z" or b == "D": - inputMask |= (1 << bit) - else: - assert(0) - bit -= 1 - return (binary, inputMask) - - def __stringVectorReplace(self, strVec, replace, data): - ret = "" - for i in range(len(strVec) - 1, -1, -1): - b = strVec[i] - if b == replace: - if (data & 1): - ret = "1" + ret - else: - ret = "0" + ret - data >>= 1 - else: - ret = b + ret - return ret - - def __bitbangStringVector(self, strVec): - vectorSize = len(strVec) - (vector, inputMask) = self.__stringVectorToBinary(strVec) - inputData = 0 - self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0) - for i in range(vectorSize - 1, -1, -1): - if inputMask & (1 << i): - self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=1, SCLK_z=0) - self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0) - self.top.cmdDelay(0.000001) - sdata = self.__getSDATA() - inputData |= (sdata << i) - else: - self.__setBitbang(SDATA=(vector & (1 << i)), SDATA_in=0, - SCLK=1, SCLK_z=0) - self.__setBitbang(SDATA=0, SDATA_in=0, SCLK=0, SCLK_z=0) - self.top.cmdDelay(0.000001) - return inputData - - def __bitbangStringVectors(self, strVecList): - for strVec in strVecList: - self.__bitbangStringVector(strVec) - - def __uploadStringVector(self, strVec): - (vector, inputMask) = self.__stringVectorToBinary(strVec) - assert(inputMask == 0) - self.top.cmdFPGAWrite(0x12, vector & 0xFF) - self.top.cmdFPGAWrite(0x13, (vector >> 8) & 0xFF) - self.top.cmdFPGAWrite(0x14, (vector >> 8) & 0xFF) - -ChipDescription( - Chip_M8C_ISSP, - bitfile = "m8c-issp", - runtimeID = (0x0007, 0x01), - chipVendors = "Cypress", - description = "M8C In System Serial Programmer", - packages = ( ("M8C ISSP header", "Special adapter"), ), - comment = "Special adapter required", - broken = True -) diff --git a/libtoprammer/chip_unitest.py b/libtoprammer/chip_unitest.py deleted file mode 100644 index 2cdb72b..0000000 --- a/libtoprammer/chip_unitest.py +++ /dev/null @@ -1,171 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Universal device tester -# -# Copyright (c) 2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_Unitest(Chip): - def __init__(self, chipPackage=None, chipPinVCC=None, chipPinsVPP=None, chipPinGND=None, - VCCVoltage=None, VPPVoltage=None): - Chip.__init__(self, chipPackage=chipPackage, chipPinVCC=chipPinVCC, - chipPinsVPP=chipPinsVPP, chipPinGND=chipPinGND) - self.autogenVCCVoltage = VCCVoltage - self.autogenVPPVoltage = VPPVoltage - - def shutdownChip(self): - self.printDebug("Shutdown chip") - self.reset() - - def reset(self): - self.top.vcc.setLayoutPins( [] ) - self.vccMask = 0 - self.top.vpp.setLayoutPins( [] ) - self.vppMask = 0 - self.top.gnd.setLayoutPins( [] ) - self.gndMask = 0 - self.top.cmdSetVCCVoltage(self.top.vcc.minVoltage()) - self.top.cmdSetVPPVoltage(self.top.vpp.minVoltage()) - self.oscMask = 0 - self.setOutputEnableMask(0) - self.setOutputs(0) - self.setOscMask(0) - self.top.flushCommands() - - def setVCC(self, voltage, layout): - self.vccMask = self.top.vcc.ID2mask(layout) - self.__updateOutEn() - self.top.cmdSetVCCVoltage(voltage) - self.top.vcc.setLayoutID(layout) - self.top.flushCommands() - - def setVPP(self, voltage, layouts): - self.vppMask = 0 - for layout in layouts: - self.vppMask |= self.top.vpp.ID2mask(layout) - self.__updateOutEn() - self.top.cmdSetVPPVoltage(voltage) - self.top.vpp.setLayoutMask(0) # Reset - for layout in layouts: - self.top.vpp.setLayoutID(layout) - self.top.flushCommands() - - def setGND(self, layout): - self.gndMask = self.top.gnd.ID2mask(layout) - self.__updateOutEn() - self.top.gnd.setLayoutID(layout) - self.top.flushCommands() - - # Overloaded layout generator interface. - def applyVCC(self, turnOn): - layoutID = 0 - if turnOn: - (layoutID, layoutMask) = self.generator.getVCCLayout() - self.setVCC(self.autogenVCCVoltage, layoutID) - - # Overloaded layout generator interface. - def applyVPP(self, turnOn, packagePinsToTurnOn=[]): - assert(not packagePinsToTurnOn) # Not supported, yet. - layouts = [] - if turnOn: - layouts = map(lambda (layoutID, layoutMask): layoutID, - self.generator.getVPPLayouts()) - self.setVPP(self.autogenVPPVoltage, layouts) - - # Overloaded layout generator interface. - def applyGND(self, turnOn): - layoutID = 0 - if turnOn: - (layoutID, layoutMask) = self.generator.getGNDLayout() - self.setGND(layoutID) - - def __updateOutEn(self): - mask = self.desiredOutEnMask - mask &= ~self.gndMask - mask &= ~self.vccMask - mask &= ~self.vppMask - mask |= self.oscMask - self.top.cmdFPGAWrite(0x50, mask & 0xFF) - self.top.cmdFPGAWrite(0x51, (mask >> 8) & 0xFF) - self.top.cmdFPGAWrite(0x52, (mask >> 16) & 0xFF) - self.top.cmdFPGAWrite(0x53, (mask >> 24) & 0xFF) - self.top.cmdFPGAWrite(0x54, (mask >> 32) & 0xFF) - self.top.cmdFPGAWrite(0x55, (mask >> 40) & 0xFF) - self.top.flushCommands() - - def setOutputEnableMask(self, mask): - self.desiredOutEnMask = mask - self.__updateOutEn() - - def __updateOut(self): - mask = self.desiredOutMask - mask &= ~self.oscMask - self.top.cmdFPGAWrite(0x70, mask & 0xFF) - self.top.cmdFPGAWrite(0x71, (mask >> 8) & 0xFF) - self.top.cmdFPGAWrite(0x72, (mask >> 16) & 0xFF) - self.top.cmdFPGAWrite(0x73, (mask >> 24) & 0xFF) - self.top.cmdFPGAWrite(0x74, (mask >> 32) & 0xFF) - self.top.cmdFPGAWrite(0x75, (mask >> 40) & 0xFF) - self.top.flushCommands() - - def setOutputs(self, mask): - self.desiredOutMask = mask - self.__updateOut() - - def getInputs(self): - self.top.cmdFPGARead(0x30) - self.top.cmdFPGARead(0x31) - self.top.cmdFPGARead(0x32) - self.top.cmdFPGARead(0x33) - self.top.cmdFPGARead(0x34) - self.top.cmdFPGARead(0x35) - inputs = self.top.cmdReadBufferReg48() - return inputs - - def getOscFreq(self): - return self.top.getOscillatorHz() - - def setOscDivider(self, div): - self.top.cmdFPGAWrite(0x12, div & 0xFF) - self.top.cmdFPGAWrite(0x13, (div >> 8) & 0xFF) - self.top.cmdFPGAWrite(0x14, (div >> 16) & 0xFF) - self.top.cmdFPGAWrite(0x15, (div >> 24) & 0xFF) - self.top.flushCommands() - - def setOscMask(self, mask): - self.oscMask = mask - self.top.cmdFPGAWrite(0x30, mask & 0xFF) - self.top.cmdFPGAWrite(0x31, (mask >> 8) & 0xFF) - self.top.cmdFPGAWrite(0x32, (mask >> 16) & 0xFF) - self.top.cmdFPGAWrite(0x33, (mask >> 24) & 0xFF) - self.top.cmdFPGAWrite(0x34, (mask >> 32) & 0xFF) - self.top.cmdFPGAWrite(0x35, (mask >> 40) & 0xFF) - self.__updateOutEn() - self.__updateOut() - self.top.flushCommands() - -ChipDescription( - Chip_Unitest, - bitfile = "unitest", - runtimeID = (0x0008, 0x01), - chipType = ChipDescription.TYPE_INTERNAL, - description = "Universal device tester", -) diff --git a/libtoprammer/chip_w29ee011dip32.py b/libtoprammer/chip_w29ee011dip32.py deleted file mode 100644 index 087c529..0000000 --- a/libtoprammer/chip_w29ee011dip32.py +++ /dev/null @@ -1,254 +0,0 @@ -""" -# TOP2049 Open Source programming suite -# -# Winbond W29EE011 DIP32 -# Winbond W29EE011 PLCC32 (inside 1:1 PLCC32->DIP32 adapter) -# -# Copyright (c) 2010 Michael Buesch -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" - -from chip import * - - -class Chip_w29ee011dip32(Chip): - PROGCMD_WRITEBUF = 1 # Write buffer to chip - - STAT_BUSY = 0x01 # Programmer is running a command - - def __init__(self): - Chip.__init__(self, - chipPackage = "DIP32", - chipPinVCC = 32, - chipPinsVPP = None, - chipPinGND = 16) - - def erase(self): - self.applyVCC(True) - self.applyVPP(True) - self.applyGND(True) - - commands = ( - (0x5555, 0xAA), - (0x2AAA, 0x55), - (0x5555, 0x80), - (0x5555, 0xAA), - (0x2AAA, 0x55), - (0x5555, 0x10), - ) - - self.progressMeterInit("Erasing chip", 0) - self.__setCEOE(CE=0, OE=1) - - self.__resetBufferPointers() - self.__swDataProtect(False) - self.__runCommandSync(self.PROGCMD_WRITEBUF) - self.top.hostDelay(0.05) - self.__resetBufferPointers() - for command in commands: - self.__appendJEDEC(command[0], command[1]) - self.__runCommandSync(self.PROGCMD_WRITEBUF) - self.top.hostDelay(0.05) - - self.__setCEOE(CE=1, OE=1) - self.progressMeterFinish() - - def readEEPROM(self): - self.applyVCC(True) - self.applyVPP(True) - self.applyGND(True) - - self.progressMeterInit("Reading EEPROM", 0x20000) - self.__setCEOE(CE=0, OE=0) - image = self.__readRange(0, 0x20000, progress=True) - self.__setCEOE(CE=1, OE=1) - self.progressMeterFinish() - - return image - - def __readRange(self, baseAddress, size, progress=False): - image = "" - byteCount = 0 - prevAddr = baseAddress - self.__loadReadAddrLo(baseAddress) - self.__loadReadAddrMed(baseAddress >> 8) - self.__loadReadAddrHi(baseAddress >> 16) - for offset in range(0, size): - addr = baseAddress + offset - if progress: - self.progressMeter(addr) - if (addr & 0xFF) != (prevAddr & 0xFF): - self.__loadReadAddrLo(addr) - if (addr & 0xFF00) != (prevAddr & 0xFF00): - self.__loadReadAddrMed(addr >> 8) - if (addr & 0xFF0000) != (prevAddr & 0xFF0000): - self.__loadReadAddrHi(addr >> 16) - prevAddr = addr - self.top.cmdFPGARead(0x10) - byteCount += 1 - if byteCount == self.top.getBufferRegSize(): - image += self.top.cmdReadBufferReg(byteCount) - byteCount = 0 - image += self.top.cmdReadBufferReg(byteCount) - return image - - def writeEEPROM(self, image): - if len(image) > 0x20000: - self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ - (len(image), 0x20000)) - - self.applyVCC(True) - self.applyVPP(True) - self.applyGND(True) - - self.progressMeterInit("Writing EEPROM", len(image)) - self.__setCEOE(CE=0, OE=1) - for addr in range(0, len(image), 128): - self.progressMeter(addr) - pagelen = min(128, len(image) - addr) - page = image[addr:addr+pagelen] - self.__writePage(addr, page) - self.__setCEOE(CE=1, OE=1) - self.progressMeterFinish() - - def __swDataProtect(self, enable): - if enable: - jedecCommands = ( - (0x5555, 0xAA), - (0x2AAA, 0x55), - (0x5555, 0xA0), - ) - else: - jedecCommands = ( - (0x5555, 0xAA), - (0x2AAA, 0x55), - (0x5555, 0x80), - (0x5555, 0xAA), - (0x2AAA, 0x55), - (0x5555, 0x20), - ) - for command in jedecCommands: - self.__appendJEDEC(command[0], command[1]) - - def __writePage(self, pageAddress, pageData): - for t in range(0, 15): - self.__resetBufferPointers() - self.__swDataProtect(True) - assert(len(pageData) <= 128) - for byte in pageData: - self.__writeBufAppend(byte2int(byte)) - self.__loadWriteAddr(pageAddress) - self.__runCommandSync(self.PROGCMD_WRITEBUF) - self.top.hostDelay(0.01) - # Verify - self.__setCEOE(CE=0, OE=0) - verifyImage = self.__readRange(pageAddress, len(pageData)) - self.__setCEOE(CE=0, OE=1) - if verifyImage == pageData: - break - self.top.hostDelay(0.1) - else: - self.throwError("Verify error on page write at address 0x%05X" % pageAddress) - - def __writeBufAppend(self, byte): - # This also auto-increments the write buffer pointer - self.top.cmdFPGAWrite(0x10, byte & 0xFF) - - def __resetBufferPointers(self): - self.top.cmdFPGAWrite(0x13, 0) - - def __loadCommand(self, command): - self.top.cmdFPGAWrite(0x12, command & 0xFF) - - def __runCommandSync(self, command): - self.__loadCommand(command) - self.__busyWait() - - def __loadWriteAddr(self, addr): - self.__loadWriteAddrLo(addr) - self.__loadWriteAddrMed(addr >> 8) - self.__loadWriteAddrHi(addr >> 16) - - def __loadWriteAddrLo(self, addrLo): - self.top.cmdFPGAWrite(0x14, addrLo & 0xFF) - - def __loadWriteAddrMed(self, addrMed): - self.top.cmdFPGAWrite(0x15, addrMed & 0xFF) - - def __loadWriteAddrHi(self, addrHi): - self.top.cmdFPGAWrite(0x16, addrHi & 0xFF) - - def __loadReadAddrLo(self, addrLo): - self.top.cmdFPGAWrite(0x17, addrLo & 0xFF) - - def __loadReadAddrMed(self, addrMed): - self.top.cmdFPGAWrite(0x18, addrMed & 0xFF) - - def __loadReadAddrHi(self, addrHi): - self.top.cmdFPGAWrite(0x19, addrHi & 0xFF) - - def __setCEOE(self, CE, OE): - data = 0 - if CE: - data |= 0x01 - if OE: - data |= 0x02 - self.top.cmdFPGAWrite(0x1A, data) - - def __appendJEDEC(self, addr, data): - self.__loadJEDECAddrLo(addr) - self.__loadJEDECAddrMed(addr >> 8) - self.__loadJEDECAddrHi(addr >> 16) - self.__loadJEDECData(data) - - def __loadJEDECAddrLo(self, addrLo): - self.top.cmdFPGAWrite(0x1B, addrLo & 0xFF) - - def __loadJEDECAddrMed(self, addrMed): - self.top.cmdFPGAWrite(0x1C, addrMed & 0xFF) - - def __loadJEDECAddrHi(self, addrHi): - self.top.cmdFPGAWrite(0x1D, addrHi & 0xFF) - - def __loadJEDECData(self, data): - # This also auto-increments the JEDEC buffer pointer - self.top.cmdFPGAWrite(0x1E, data & 0xFF) - - 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, 100): - if not self.__busy(): - return - self.top.hostDelay(0.01) - self.throwError("Timeout in busywait.") - -ChipDescription( - Chip_w29ee011dip32, - bitfile = "w29ee011dip32", - runtimeID = (0x0009, 0x01), - chipType = ChipDescription.TYPE_EEPROM, - chipVendors = "Winbond", - description = "W29EE011 EEPROM", - packages = ( ("DIP32", ""), ("PLCC32", "Use 1:1 PLCC32->DIP32 adapter"), ), - broken = True, -) diff --git a/libtoprammer/chip_xxxx.py b/libtoprammer/chip_xxxx.py deleted file mode 100644 index 2193b1c..0000000 --- a/libtoprammer/chip_xxxx.py +++ /dev/null @@ -1,15 +0,0 @@ -# Import all chip modules in alphabetical order -from chip_74hc4094 import * -from chip_at27c256r import * -from chip_at89c2051dip20 import * -from chip_atmega32dip40 import * -from chip_atmega8dip28 import * -from chip_atmega88dip28 import * -from chip_attiny13dip8 import * -from chip_attiny26dip20 import * -from chip_hm62256dip28 import * -from chip_m24cxxdip8 import * -from chip_m2764a import * -from chip_m8cissp import * -from chip_unitest import * -from chip_w29ee011dip32 import * diff --git a/libtoprammer/chips/_74hc4094.py b/libtoprammer/chips/_74hc4094.py new file mode 100644 index 0000000..e04d63e --- /dev/null +++ b/libtoprammer/chips/_74hc4094.py @@ -0,0 +1,150 @@ +""" +# TOP2049 Open Source programming suite +# +# 74HC4094 unit-tester +# +# Copyright (c) 2011 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 unitest import * + +class Chip_74hc4094(Chip_Unitest): + def __init__(self): + Chip_Unitest.__init__(self, chipPackage="DIP16", + chipPinVCC=16, + chipPinGND=8, + VCCVoltage=5) + + def __initChip(self): + self.zifPin_STR = self.generator.getZifPinForPackagePin(1) + self.zifPin_D = self.generator.getZifPinForPackagePin(2) + self.zifPin_CP = self.generator.getZifPinForPackagePin(3) + self.zifPin_OE = self.generator.getZifPinForPackagePin(15) + self.zifPin_QS1 = self.generator.getZifPinForPackagePin(9) + self.zifPin_QS2 = self.generator.getZifPinForPackagePin(10) + self.zifPins_QP = [] + for packagePin in (4, 5, 6, 7, 14, 13, 12, 11): + self.zifPins_QP.append( + self.generator.getZifPinForPackagePin(packagePin)) + + self.reset() + + outen = 0 + for zifPin in (self.zifPin_STR, self.zifPin_D, + self.zifPin_CP, self.zifPin_OE): + outen |= (1 << (zifPin - 1)) + self.setOutputEnableMask(outen) + + self.applyGND(True) + self.applyVCC(True) + + def test(self): + testPatterns = (0xFF, 0x00, 0xAA, 0x55, 0xF0, 0x0F, + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00) + + self.progressMeterInit("Logic test", len(testPatterns)) + self.__initChip() + + # Initialize the register to all-zero + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) + for i in range(0, 9): + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=1, OE=0)) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) + self.setOutputs(self.__makeOutMask(STR=1, D=0, CP=0, OE=0)) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=1)) + + QP = self.__readQP() + if QP != 0x00: + self.throwError("Failed to clear the shiftregister. Got 0x%02X" % QP) + + prevContents = 0x00 + prev_QS1 = False + count = 0 + for testPattern in testPatterns: + self.progressMeter(count) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) + for bitNr in range(7, -1, -1): # MSB first + self.setOutputs(self.__makeOutMask(STR=0, + D=(testPattern & (1 << bitNr)), + CP=0, OE=0)) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=1, OE=0)) + (QS1, QS2) = self.__readQS() + word = (prevContents << 8) | testPattern + expect_QS1 = bool(word & (1 << (bitNr + 7))) + expect_QS2 = prev_QS1 + prev_QS1 = expect_QS1 + if QS1 != expect_QS1 or QS2 != expect_QS2: + self.throwError("Got invalid QS serial output for " + "test pattern 0x%02X bit %d. Got %d/%d, but " + "expected %d/%d" %\ + (testPattern, bitNr, QS1, QS2, + expect_QS1, expect_QS2)) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=0)) + self.setOutputs(self.__makeOutMask(STR=1, D=0, CP=0, OE=0)) + self.setOutputs(self.__makeOutMask(STR=0, D=0, CP=0, OE=1)) + + QP = self.__readQP() + if QP != testPattern: + self.throwError("Failed on test pattern 0x%02X. Got 0x%02X" %\ + (testPattern, QP)) + + prevContents = testPattern + count += 1 + self.progressMeterFinish() + + def __makeOutMask(self, STR, D, CP, OE): + mask = 0 + if STR: + mask |= (1 << (self.zifPin_STR - 1)) + if D: + mask |= (1 << (self.zifPin_D - 1)) + if CP: + mask |= (1 << (self.zifPin_CP - 1)) + if OE: + mask |= (1 << (self.zifPin_OE - 1)) + return mask + + def __readQP(self): + QPValue = 0 + count = 0 + inputs = self.getInputs() + for zifPin in self.zifPins_QP: + if inputs & (1 << (zifPin - 1)): + QPValue |= (1 << count) + count += 1 + return QPValue + + def __readQS(self): + QS1 = False + QS2 = False + inputs = self.getInputs() + if inputs & (1 << (self.zifPin_QS1 - 1)): + QS1 = True + if inputs & (1 << (self.zifPin_QS2 - 1)): + QS2 = True + return (QS1, QS2) + +ChipDescription( + Chip_74hc4094, + chipID = "74hc4094dip16", + bitfile = "unitest", + runtimeID = (0x0008, 0x01), + chipType = ChipDescription.TYPE_LOGIC, + description = "74HC(T)4094 shift-register", + chipVendors = ("Philips", "Other"), +) diff --git a/libtoprammer/chips/__init__.py b/libtoprammer/chips/__init__.py new file mode 100644 index 0000000..32ee95d --- /dev/null +++ b/libtoprammer/chips/__init__.py @@ -0,0 +1,15 @@ +# Import all chip modules in alphabetical order +from _74hc4094 import * +from at27c256r import * +from at89c2051dip20 import * +from atmega32dip40 import * +from atmega8dip28 import * +from atmega88dip28 import * +from attiny13dip8 import * +from attiny26dip20 import * +from hm62256dip28 import * +from m24cxxdip8 import * +from m2764a import * +from m8cissp import * +from unitest import * +from w29ee011dip32 import * diff --git a/libtoprammer/chips/at27c256r.py b/libtoprammer/chips/at27c256r.py new file mode 100644 index 0000000..9dff427 --- /dev/null +++ b/libtoprammer/chips/at27c256r.py @@ -0,0 +1,82 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel AT27C256R EPROM +# +# Copyright (c) 2012 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_at27c256r(Chip): + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP28", + chipPinVCC = 28, + chipPinsVPP = 1, + chipPinGND = 14) + self.sizeBytes = 32 * 1024 + self.generic = GenericAlgorithms(self) + self.addrSetter = AddrSetter(self, 0x10, 0x11) + + def readEEPROM(self): + self.__turnOn() + return self.generic.simpleReadEPROM( + sizeBytes = self.sizeBytes, + readData8Func = self.__dataRead, + addrSetter = self.addrSetter, + initFunc = lambda: self.__setFlags(oe=0, ce=0), + exitFunc = lambda: self.__setFlags(oe=1, ce=1) + ) + +# def writeEEPROM(self): +# pass#TODO + + def __turnOn(self): + self.__setFlags() + self.generic.simpleVoltageSetup() + + def __setDataPins(self, value): + self.top.cmdFPGAWrite(0x12, value) + + def __setFlags(self, data_en=0, prog_en=0, ce=1, oe=1): + value = 0 + if data_en: + value |= (1 << 0) + if prog_en: + value |= (1 << 1) + if ce: + value |= (1 << 2) + if oe: + value |= (1 << 3) + self.top.cmdFPGAWrite(0x13, value) + + def __progPulse(self): + self.top.cmdFPGAWrite(0x14, 0) + + def __dataRead(self): + self.top.cmdFPGARead(0x10) + +ChipDescription(Chip_at27c256r, + bitfile = "at27c256r", + runtimeID = (0x000C, 0x01), + chipType = ChipDescription.TYPE_EPROM, + chipVendors = "Atmel", + description = "AT27C256R", + packages = ( ("DIP28", ""), ) +) diff --git a/libtoprammer/chips/at89c2051dip20.py b/libtoprammer/chips/at89c2051dip20.py new file mode 100644 index 0000000..c23a89d --- /dev/null +++ b/libtoprammer/chips/at89c2051dip20.py @@ -0,0 +1,230 @@ +""" +# 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_AT89C2051dip20(Chip): + STAT_BUSY = 0x01 # Programmer is running a command + STAT_ERR = 0x02 # Error during write + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP20", + chipPinVCC = 20, + chipPinsVPP = 1, + chipPinGND = 10) + + 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.applyGND(True) + self.applyVCC(True) + self.top.cmdSetVPPVoltage(5) + self.__loadCommand(5) # VPP on + self.__loadCommand(1) # set P3.2 + self.__setP3x(P33=0, P34=0, P35=0, IA=0) + data = "" + self.top.cmdFPGARead(0x10) + self.__setP3x(P33=0, P34=0, P35=0, IA=1) + self.__setP3x(P33=0, P34=0, P35=0, IA=0) + self.top.cmdFPGARead(0x10) + self.__setP3x(P33=0, P34=0, P35=0, IA=1) + self.__setP3x(P33=0, P34=0, P35=0, IA=0) + self.top.cmdFPGARead(0x10) + data += self.top.cmdReadBufferReg() + self.__setP3x(P33=0, P34=1, P35=0, IA=0) + 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.applyVPP(True) + self.__loadCommand(5) # VPP on + self.__setP3x(P33=1, P34=0, P35=0, IA=0) + self.top.cmdSetVPPVoltage(12) + self.__runCommandSync(4) + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setP3x(P33=0, P34=1, P35=0, IA=0) + self.__loadCommand(5) # VPP off + self.top.flushCommands() + self.top.printInfo("at89c2051dip20: Erasing flash, verifying ...") + ok = self.__verifyErase() + if ok == 0: + self.top.printInfo("at89c2051dip20: Erase done.") + else: + self.top.printInfo("at89c2051dip20: Erase failed!") + + def readProgmem(self): + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.applyVPP(True) + self.__loadCommand(5) # VPP on + self.__setP3x(P33=0, P34=0, P35=1, IA=0) + image = "" + byteCount = 0 + self.progressMeterInit("Reading Flash", 0x800) + for addr in range(0, 0x800): + self.progressMeter(addr) + self.top.cmdFPGARead(0x10) + self.__setP3x(P33=0, P34=0, P35=1, IA=1) + self.__setP3x(P33=0, P34=0, P35=1, IA=0) + byteCount += 1 + if byteCount == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(byteCount) + byteCount = 0 + image += self.top.cmdReadBufferReg(byteCount) + self.applyVPP(False) + self.__setP3x(P33=0, P34=1, P35=0, IA=0) + self.__loadCommand(5) # VPP off + self.top.flushCommands() + self.progressMeterFinish() + + return image + + def writeProgmem(self, image): + if len(image) > 0x800: + self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ + (len(image), 0x800)) + self.__initChip() + self.applyGND(True) + self.applyVCC(True) + self.__loadCommand(1) # set P3.2 + self.top.cmdSetVPPVoltage(5) + self.applyVPP(True) + self.__loadCommand(5) # VPP on + self.__setP3x(P33=0, P34=1, P35=1, IA=0) + 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.__loadCommand(3) + ok = self.__progWait() + if (ok & self.STAT_ERR) != 0: + self.throwError("Write byte failed.") + self.__setP3x(P33=0, P34=1, P35=1, IA=1) + self.__setP3x(P33=0, P34=1, P35=1, IA=0) + self.applyVPP(False) + self.top.cmdSetVPPVoltage(5) + self.__setP3x(P33=0, P34=1, P35=0, IA=0) + self.__loadCommand(5) # VPP off + self.top.flushCommands() + self.progressMeterFinish() + ok = self.__verifyProgmem(image) + if ok == 0: + self.top.printInfo("at89c2051dip20: Write flash done.") + else: + self.top.printInfo("at89c2051dip20: Write flash failed!") + + def __verifyErase(self): + ok = 0 + image = self.readProgmem() + for addr in range(0, 0x800): + if byte2int(image[addr]) != 0xFF: + ok = 1 + return ok + + def __verifyProgmem(self,image): + data = self.readProgmem() + ok = 0 + for addr in range(0, 0x800): + if byte2int(image[addr]) != byte2int(data[addr]): + ok = 1 + return ok + + def __loadData(self, data): + self.top.cmdFPGAWrite(0x10, data) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setP3x(self, P33, P34, P35, IA): + data = 0 + if P33: + data |= 1 + if P34: + data |= 2 + if P35: + data |= 4 + if IA: + data |= 8 + 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.") + +ChipDescription( + Chip_AT89C2051dip20, + bitfile = "at89c2051dip20", + runtimeID = (0x0005, 0x01), + chipVendors = "Atmel", + description = "AT89C2051", + maintainer = None, + packages = ( ("DIP20", ""), ) +) diff --git a/libtoprammer/chips/atmega32dip40.py b/libtoprammer/chips/atmega32dip40.py new file mode 100644 index 0000000..486cec3 --- /dev/null +++ b/libtoprammer/chips/atmega32dip40.py @@ -0,0 +1,47 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel Mega32 DIP40 support +# +# Copyright (c) 2009-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 atmega_common import * + + +class Chip_ATMega32DIP40(Chip_ATMega_common): + def __init__(self): + Chip_ATMega_common.__init__(self, + chipPackage = "DIP40", + chipPinVCC = 10, + chipPinsVPP = 9, + chipPinGND = 11, + signature = "\x1E\x95\x02", + flashPageSize = 64, + flashPages = 256, + eepromPageSize = 4, + eepromPages = 256) + +ChipDescription( + Chip_ATMega32DIP40, + bitfile = "atmega32dip40", + runtimeID = (0x0004, 0x01), + chipVendors = "Atmel", + description = "AtMega32", + packages = ( ("DIP40", ""), ), + comment = "Insert upside down into ZIF socket" +) diff --git a/libtoprammer/chips/atmega88dip28.py b/libtoprammer/chips/atmega88dip28.py new file mode 100644 index 0000000..de1fc2b --- /dev/null +++ b/libtoprammer/chips/atmega88dip28.py @@ -0,0 +1,47 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel Mega88 DIP28 support +# +# Copyright (c) 2009-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 atmega_common import * + + +class Chip_ATMega88DIP28(Chip_ATMega_common): + def __init__(self): + Chip_ATMega_common.__init__(self, + chipPackage = "DIP28", + chipPinVCC = 7, + chipPinsVPP = 1, + chipPinGND = 8, + signature = "\x1E\x93\x0A", + flashPageSize = 32, + flashPages = 128, + eepromPageSize = 4, + eepromPages = 128) + +ChipDescription( + Chip_ATMega88DIP28, + bitfile = "atmega8dip28", + chipID = "atmega88dip28", + runtimeID = (0x0003, 0x01), + chipVendors = "Atmel", + description = "AtMega88", + packages = ( ("DIP28", ""), ), +) diff --git a/libtoprammer/chips/atmega8dip28.py b/libtoprammer/chips/atmega8dip28.py new file mode 100644 index 0000000..6b680bb --- /dev/null +++ b/libtoprammer/chips/atmega8dip28.py @@ -0,0 +1,79 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel Mega8 DIP28 support +# +# Copyright (c) 2009-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 atmega_common import * + + +class Chip_ATMega8DIP28(Chip_ATMega_common): + def __init__(self): + Chip_ATMega_common.__init__(self, + chipPackage = "DIP28", + chipPinVCC = 7, + chipPinsVPP = 1, + chipPinGND = 8, + signature = "\x1E\x93\x07", + flashPageSize = 32, + flashPages = 128, + eepromPageSize = 4, + eepromPages = 128) + +fuseDesc = ( + BitDescription(0, "CKSEL0"), + BitDescription(1, "CKSEL1"), + BitDescription(2, "CKSEL2"), + BitDescription(3, "CKSEL3"), + BitDescription(4, "SUT0"), + BitDescription(5, "SUT1"), + BitDescription(6, "BODEN"), + BitDescription(7, "BODLEVEL"), + BitDescription(8, "BOOTRST"), + BitDescription(9, "BOOTSZ0"), + BitDescription(10, "BOOTSZ1"), + BitDescription(11, "EESAVE"), + BitDescription(12, "CKOPT"), + BitDescription(13, "SPIEN"), + BitDescription(14, "WDTON"), + BitDescription(15, "RSTDISBL"), +) + +lockbitDesc = ( + BitDescription(0, "LB1"), + BitDescription(1, "LB2"), + BitDescription(2, "BLB01"), + BitDescription(3, "BLB02"), + BitDescription(4, "BLB11"), + BitDescription(5, "BLB12"), + BitDescription(6, "Unused"), + BitDescription(7, "Unused"), + BitDescription(8, "Unused"), +) + +ChipDescription( + Chip_ATMega8DIP28, + bitfile = "atmega8dip28", + runtimeID = (0x0003, 0x01), + chipVendors = "Atmel", + description = "AtMega8", + fuseDesc = fuseDesc, + lockbitDesc = lockbitDesc, + packages = ( ("DIP28", ""), ) +) diff --git a/libtoprammer/chips/atmega_common.py b/libtoprammer/chips/atmega_common.py new file mode 100644 index 0000000..1609528 --- /dev/null +++ b/libtoprammer/chips/atmega_common.py @@ -0,0 +1,465 @@ +""" +# TOP2049 Open Source programming suite +# +# Implements the Atmel Mega MCU parallel HV programming algorithm +# +# Copyright (c) 2009-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_ATMega_common(Chip): + # The Atmel Mega programming commands + CMD_CHIPERASE = 0x80 # Chip Erase + CMD_WRITEFUSE = 0x40 # Write Fuse Bits + CMD_WRITELOCK = 0x20 # Write Lock Bits + CMD_WRITEFLASH = 0x10 # Write Flash + CMD_WRITEEEPROM = 0x11 # Write EEPROM + CMD_READSIG = 0x08 # Read Signature bytes and Calibration byte + CMD_READFUSELOCK = 0x04 # Read Fuse and Lock bits + CMD_READFLASH = 0x02 # Read Flash + CMD_READEEPROM = 0x03 # Read EEPROM + + def __init__(self, + chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, + signature, + flashPageSize, flashPages, + eepromPageSize, eepromPages + ): + 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 + + def readSignature(self): + self.__enterPM() + + (signature, calibration) = self.__readSigAndCalib() + + return signature + + def erase(self): + self.__enterPM() + + self.progressMeterInit("Erasing chip", 0) + self.__loadCommand(self.CMD_CHIPERASE) + self.__pulseWR() + self.__waitForRDY() + self.progressMeterFinish() + + def readProgmem(self): + self.__enterPM() + + self.progressMeterInit("Reading Flash", self.flashPages) + image = "" + for page in range(0, self.flashPages): + self.progressMeter(page) + readWords = 0 + for word in range(0, self.flashPageSize): + self.__loadCommand(self.CMD_READFLASH) + self.__loadAddr((page * self.flashPageSize) + word) + self.__readWordToStatusReg() + readWords += 1 + if readWords >= 32: + image += self.top.cmdReadBufferReg() + readWords = 0 + if readWords: + data = self.top.cmdReadBufferReg() + image += data[0:readWords*2] + self.progressMeterFinish() + return image + + def writeProgmem(self, image): + flashBytes = self.flashPageSize * 2 * self.flashPages + if len(image) != flashBytes: + self.throwError("Invalid program memory image size %d (expected %d)" %\ + (len(image), flashBytes)) + self.__enterPM() + + self.progressMeterInit("Writing Flash", self.flashPages) + for page in range(0, self.flashPages): + self.progressMeter(page) + for word in range(0, self.flashPageSize): + self.__loadCommand(self.CMD_WRITEFLASH) + addr = (page * self.flashPageSize) + word + self.__loadAddr(addr) + addr *= 2 + data = image[addr : addr + 2] + self.__loadData(byte2int(data[0]) | (byte2int(data[1]) << 8)) + self.__setBS1(1) + self.__pulsePAGEL() + self.__setBS1(0) + self.__pulseWR() + self.__waitForRDY() + self.progressMeterFinish() + + def readEEPROM(self): + self.__enterPM() + + assert(self.eepromPageSize <= self.top.getBufferRegSize()) + self.progressMeterInit("Reading EEPROM", self.eepromPages) + image = "" + for page in range(0, self.eepromPages): + self.progressMeter(page) + for byte in range(0, self.eepromPageSize): + self.__loadCommand(self.CMD_READEEPROM) + self.__loadAddr((page * self.eepromPageSize) + byte) + self.__readLowByteToStatusReg() + data = self.top.cmdReadBufferReg() + image += data[0:self.eepromPageSize] + self.progressMeterFinish() + return image + + def writeEEPROM(self, image): + eepromBytes = self.eepromPageSize * self.eepromPages + if len(image) != eepromBytes: + self.throwError("Invalid EEPROM image size %d (expected %d)" %\ + (len(image), eepromBytes)) + self.__enterPM() + + self.progressMeterInit("Writing EEPROM", self.eepromPages) + for page in range(0, self.eepromPages): + self.progressMeter(page) + for byte in range(0, self.eepromPageSize): + self.__loadCommand(self.CMD_WRITEEEPROM) + addr = (page * self.eepromPageSize) + byte + self.__loadAddr(addr) + data = image[addr] + self.__loadDataLow(byte2int(data[0])) + self.__pulsePAGEL() + self.__setBS1(0) + self.__pulseWR() + self.__waitForRDY() + self.progressMeterFinish() + + def readFuse(self): + self.__enterPM() + + self.progressMeterInit("Reading Fuse bits", 0) + (fuse, lock) = self.__readFuseAndLockBits() + self.progressMeterFinish() + return fuse + + def writeFuse(self, image): + if len(image) != 2: + self.throwError("Invalid Fuses image size %d (expected %d)" %\ + (len(image), 2)) + self.__enterPM() + + self.progressMeterInit("Writing Fuse bits", 0) + self.__loadCommand(self.CMD_WRITEFUSE) + self.__setBS2(0) + self.__loadDataLow(byte2int(image[0])) + self.__pulseWR() + self.__waitForRDY() + self.__loadCommand(self.CMD_WRITEFUSE) + self.__loadDataLow(byte2int(image[1])) + self.__setBS1(1) + self.__pulseWR() + self.__waitForRDY() + self.progressMeterFinish() + + def readLockbits(self): + self.__enterPM() + + self.progressMeterInit("Reading lock bits", 0) + (fuses, lockbits) = self.__readFuseAndLockBits() + self.progressMeterFinish() + + return lockbits + + def writeLockbits(self, image): + if len(image) != 1: + self.throwError("Invalid lock-bits image size %d (expected %d)" %\ + (len(image), 1)) + self.__enterPM() + + self.progressMeterInit("Writing lock bits", 0) + self.__loadCommand(self.CMD_WRITELOCK) + self.__loadDataLow(byte2int(image[0])) + self.__pulseWR() + self.__waitForRDY() + self.progressMeterFinish() + + def __readSigAndCalib(self): + """Reads the signature and calibration bytes and returns them. + This function expects a DUT present and pins initialized.""" + signature = "" + calibration = "" + for addr in range(0, 3): + self.__loadCommand(self.CMD_READSIG) + self.__loadAddr(addr) + self.__readWordToStatusReg() + data = self.top.cmdReadBufferReg() + if addr == 0: + calibration += data[1] + signature += data[0] + return (signature, calibration) + + def __readFuseAndLockBits(self): + """Reads the Fuse and Lock bits and returns them. + This function expects a DUT present and pins initialized.""" + self.__loadCommand(self.CMD_READFUSELOCK) + self.__setBS2(0) + self.__readWordToStatusReg() + self.__setBS2(1) + self.__readWordToStatusReg() + self.__setBS2(0) + data = self.top.cmdReadBufferReg() + fuses = data[0] + data[3] + lock = data[1] + return (fuses, lock) + + def __enterPM(self): + "Enter HV programming mode." + self.applyVPP(False) + self.applyVCC(False) + self.applyGND(True) + self.top.cmdSetVPPVoltage(0) + self.top.cmdSetVPPVoltage(12) + self.top.cmdSetVCCVoltage(5) + + self.__setVoltageControl(VPP_en=1, VPP=0, VCC_en=1, VCC=0) + self.__setXA0(0) + self.__setXA1(0) + self.__setBS1(0) + self.__setPAGEL(0) + self.__setWR(0) + self.top.hostDelay(0.1) + + self.applyVCC(True) + self.__setVoltageControl(VPP_en=1, VPP=0, VCC_en=1, VCC=1) + self.top.hostDelay(0.1) + + self.__setOE(0) + self.__setWR(1) + self.__setXTAL1(0) + self.__setXA0(0) + self.__setXA1(0) + self.__setBS1(0) + self.__setBS2(0) + self.__setPAGEL(0) + self.__pulseXTAL1(10) + self.top.flushCommands() + + self.__setVoltageControl(VPP_en=0, VPP=0, VCC_en=1, VCC=1) + self.applyVPP(True) + + self.__setOE(1) + + (signature, calibration) = self.__readSigAndCalib() + 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 __readWordToStatusReg(self): + """Read a data word from the DUT into the status register.""" + self.__setBS1(0) + self.__setOE(0) + self.top.cmdFPGARead(0x10) + self.__setBS1(1) + self.top.cmdFPGARead(0x10) + self.__setOE(1) + + def __readLowByteToStatusReg(self): + """Read the low data byte from the DUT into the status register.""" + self.__setBS1(0) + self.__setOE(0) + self.top.cmdFPGARead(0x10) + self.__setOE(1) + + def __readHighByteToStatusReg(self): + """Read the high data byte from the DUT into the status register.""" + self.__setBS1(1) + self.__setOE(0) + self.top.cmdFPGARead(0x10) + self.__setOE(1) + + def __loadData(self, data): + """Load a data word.""" + self.__loadDataLow(data) + self.__loadDataHigh(data >> 8) + + def __loadDataLow(self, dataLow): + """Load the low data byte.""" + self.__setBS1(0) + self.__setXA0(1) + self.__setXA1(0) + self.top.cmdFPGAWrite(0x10, dataLow & 0xFF) + self.__pulseXTAL1() + + def __loadDataHigh(self, dataHigh): + """Load the high data byte.""" + self.__setBS1(1) + self.__setXA0(1) + self.__setXA1(0) + self.top.cmdFPGAWrite(0x10, dataHigh & 0xFF) + self.__pulseXTAL1() + + def __loadAddr(self, addr): + """Load an address word.""" + self.__loadAddrLow(addr) + self.__loadAddrHigh(addr >> 8) + + def __loadAddrLow(self, addrLow): + """Load the low address byte.""" + self.__setBS1(0) + self.__setXA0(0) + self.__setXA1(0) + self.top.cmdFPGAWrite(0x10, addrLow & 0xFF) + self.__pulseXTAL1() + + def __loadAddrHigh(self, addrHigh): + """Load the high address byte.""" + self.__setBS1(1) + self.__setXA0(0) + self.__setXA1(0) + self.top.cmdFPGAWrite(0x10, addrHigh & 0xFF) + self.__pulseXTAL1() + + def __loadCommand(self, command): + """Load a command into the device.""" +# self.top.queueCommand("\x34") + self.__setBS1(0) +# self.top.queueCommand("\x34") + self.__setXA0(0) + self.__setXA1(1) + self.top.cmdFPGAWrite(0x10, command) + self.__pulseXTAL1() + + def __waitForRDY(self): + """Wait for the RDY pin to go high.""" + self.top.hostDelay(0.01) + for i in range(0, 50): + if self.__getRDY(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout waiting for READY signal from chip.") + + def __getRDY(self): + """Read the state of the RDY/BSY pin.""" + return bool(self.__getStatus() & 0x01) + + def __getStatus(self): + """Read the programmer status register""" + self.top.cmdFPGARead(0x12) + stat = self.top.cmdReadBufferReg() + return byte2int(stat[0]) + + def __setOE(self, high): + """Set the OE pin of the DUT""" + value = 0x02 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __setWR(self, high): + """Set the WR pin of the DUT""" + value = 0x03 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __pulseWR(self, count=1): + """Do a negative pulse on the WR pin of the DUT""" + while count > 0: + self.__setWR(0) + self.__setWR(1) + count -= 1 + + def __setBS1(self, high): + """Set the BS1 pin of the DUT""" + value = 0x04 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __setXA0(self, high): + """Set the XA0 pin of the DUT""" + value = 0x05 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __setXA1(self, high): + """Set the XA1 pin of the DUT""" + value = 0x06 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __setXTAL1(self, high): + """Set the XTAL1 pin of the DUT""" + value = 0x07 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __pulseXTAL1(self, count=1): + """Do a positive pulse on the XTAL1 pin of the DUT""" + while count > 0: + self.__setXTAL1(1) + self.__setXTAL1(0) + count -= 1 + + def __setPAGEL(self, high): + """Set the PAGEL pin of the DUT""" + value = 0x09 + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __pulsePAGEL(self, count=1): + """Do a positive pulse on the PAGEL pin of the DUT""" + while count > 0: + self.__setPAGEL(1) + self.__setPAGEL(0) + count -= 1 + + def __setBS2(self, high): + """Set the BS2 pin of the DUT""" + value = 0x0A + if high: + value |= 0x80 + self.top.cmdFPGAWrite(0x12, value) + + def __setVoltageControl(self, VPP_en, VPP, VCC_en, VCC): + value = 0 + if VPP_en: + value |= 0x01 + if VPP: + value |= 0x02 + if VCC_en: + value |= 0x04 + if VCC: + value |= 0x08 + self.top.cmdFPGAWrite(0x11, value) diff --git a/libtoprammer/chips/attiny13dip8.py b/libtoprammer/chips/attiny13dip8.py new file mode 100644 index 0000000..bacd3b7 --- /dev/null +++ b/libtoprammer/chips/attiny13dip8.py @@ -0,0 +1,358 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel Tiny13 DIP8 +# +# 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_AtTiny13dip8(Chip): + PROGCMD_SENDINSTR = 1 # Send an instruction to the chip + + STAT_BUSY = 0x01 # Programmer is running a command + STAT_SDO = 0x02 # Raw SDO pin state + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP8", + chipPinVCC = 8, + chipPinsVPP = 1, + chipPinGND = 4) + self.signature = "\x1E\x90\x07" + self.flashPageSize = 16 + self.flashPages = 32 + self.eepromPageSize = 4 + self.eepromPages = 16 + + def readSignature(self): + self.__enterPM() + self.progressMeterInit("Reading signature", 0) + signature = self.__readSignature() + self.progressMeterFinish() + return signature + + def erase(self): + self.__enterPM() + self.progressMeterInit("Erasing chip", 0) + self.__sendInstr(SDI=0x80, SII=0x4C) + self.__sendInstr(SDI=0x00, SII=0x64) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__waitHighSDO() + self.__sendNOP() + self.progressMeterFinish() + + def readProgmem(self): + nrWords = self.flashPages * self.flashPageSize + image = "" + self.__enterPM() + self.progressMeterInit("Reading flash", nrWords) + self.__sendReadFlashInstr() + currentHigh = -1 + bufferedBytes = 0 + for word in range(0, nrWords): + self.progressMeter(word) + low = word & 0xFF + high = (word >> 8) & 0xFF + self.__sendInstr(SDI=low, SII=0x0C) + if high != currentHigh: + self.__sendInstr(SDI=high, SII=0x1C) + currentHigh = high + self.__sendInstr(SDI=0x00, SII=0x68) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__readSDOBufferHigh() + bufferedBytes += 1 + self.__sendInstr(SDI=0x00, SII=0x78) + self.__sendInstr(SDI=0x00, SII=0x7C) + self.__readSDOBufferHigh() + bufferedBytes += 1 + if bufferedBytes == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(bufferedBytes) + 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) + self.__sendWriteFlashInstr() + currentHigh = -1 + for word in range(0, len(image) // 2): + self.progressMeter(word) + low = word & 0xFF + high = (word >> 8) & 0xFF + self.__sendInstr(SDI=low, SII=0x0C) + self.__sendInstr(SDI=byte2int(image[word * 2 + 0]), SII=0x2C) + self.__sendInstr(SDI=byte2int(image[word * 2 + 1]), SII=0x3C) + self.__sendInstr(SDI=0x00, SII=0x7D) + self.__sendInstr(SDI=0x00, SII=0x7C) + if ((word + 1) % self.flashPageSize == 0) or word == len(image) // 2 - 1: + if currentHigh != high: + self.__sendInstr(SDI=high, SII=0x1C) + currentHigh = high + self.__sendInstr(SDI=0x00, SII=0x64) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__waitHighSDO() + self.__sendNOP() + self.progressMeterFinish() + + def readEEPROM(self): + nrBytes = self.eepromPages * self.eepromPageSize + image = "" + self.__enterPM() + self.progressMeterInit("Reading EEPROM", nrBytes) + self.__sendReadEEPROMInstr() + currentPage = -1 + bufferedBytes = 0 + for i in range(0, nrBytes): + self.progressMeter(i) + low = i & 0xFF + high = (i >> 8) & 0xFF + self.__sendInstr(SDI=low, SII=0x0C) + if currentPage != high: + self.__sendInstr(SDI=high, SII=0x1C) + currentPage = high + self.__sendInstr(SDI=0x00, SII=0x68) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__readSDOBufferHigh() + bufferedBytes += 1 + if bufferedBytes == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(bufferedBytes) + bufferedBytes = 0 + image += self.top.cmdReadBufferReg(bufferedBytes) + self.progressMeterFinish() + return image + + def writeEEPROM(self, image): + nrBytes = self.eepromPages * self.eepromPageSize + if len(image) > nrBytes: + self.throwError("Invalid EEPROM image size %d (expected <=%d)" %\ + (len(image), nrBytes)) + self.__enterPM() + self.progressMeterInit("Writing EEPROM", len(image)) + self.__sendWriteEEPROMInstr() + for i in range(0, len(image)): + self.progressMeter(i) + self.__sendInstr(SDI=i, SII=0x0C) + self.__sendInstr(SDI=byte2int(image[i]), SII=0x2C) + self.__sendInstr(SDI=0x00, SII=0x6D) + self.__sendInstr(SDI=0x00, SII=0x6C) + if ((i + 1) % self.eepromPageSize == 0) or i == len(image) - 1: + self.__sendInstr(SDI=0x00, SII=0x64) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__waitHighSDO() + self.__sendNOP() + self.progressMeterFinish() + + def readFuse(self): + fuses = [] + self.__enterPM() + self.progressMeterInit("Reading fuses", 0) + self.__sendInstr(SDI=0x04, SII=0x4C) + self.__sendInstr(SDI=0x00, SII=0x68) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__readSDOBufferHigh() + fuses.append(self.top.cmdReadBufferReg(1)) + self.__sendInstr(SDI=0x04, SII=0x4C) + self.__sendInstr(SDI=0x00, SII=0x7A) + self.__sendInstr(SDI=0x00, SII=0x7E) + self.__readSDOBufferHigh() + fuses.append(int2byte(self.top.cmdReadBufferReg8() | 0xE0)) + self.progressMeterFinish() + return b"".join(fuses) + + def writeFuse(self, image): + if len(image) != 2: + self.throwError("Invalid Fuses image size %d (expected %d)" %\ + (len(image), 2)) + self.__enterPM() + self.progressMeterInit("Writing fuses", 0) + self.__sendInstr(SDI=0x40, SII=0x4C) + self.__sendInstr(SDI=byte2int(image[0]), SII=0x2C) + self.__sendInstr(SDI=0x00, SII=0x64) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__waitHighSDO() + self.__sendInstr(SDI=0x40, SII=0x4C) + self.__sendInstr(SDI=(byte2int(image[1]) & 0x1F), SII=0x2C) + self.__sendInstr(SDI=0x00, SII=0x74) + self.__sendInstr(SDI=0x00, SII=0x7C) + self.__waitHighSDO() + self.progressMeterFinish() + + def readLockbits(self): + self.__enterPM() + self.progressMeterInit("Reading lockbits", 0) + self.__sendInstr(SDI=0x04, SII=0x4C) + self.__sendInstr(SDI=0x00, SII=0x78) + self.__sendInstr(SDI=0x00, SII=0x7C) + self.__readSDOBufferHigh() + lockbits = int2byte(self.top.cmdReadBufferReg8() | 0xFC) + self.progressMeterFinish() + return lockbits + + def writeLockbits(self, image): + if len(image) != 1: + self.throwError("Invalid Lockbits image size %d (expected %d)" %\ + (len(image), 1)) + self.__enterPM() + self.progressMeterInit("Writing lockbits", 0) + self.__sendInstr(SDI=0x20, SII=0x4C) + self.__sendInstr(SDI=(byte2int(image[0]) & 3), SII=0x2C) + self.__sendInstr(SDI=0x00, SII=0x64) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__waitHighSDO() + self.progressMeterFinish() + + def __readSignature(self): + self.__sendInstr(SDI=0x08, SII=0x4C) + for i in range(0, 3): + self.__sendInstr(SDI=i, SII=0x0C) + self.__sendInstr(SDI=0x00, SII=0x68) + self.__sendInstr(SDI=0x00, SII=0x6C) + self.__readSDOBufferHigh() + return self.top.cmdReadBufferReg()[0:3] + + def __enterPM(self): + "Enter HV programming mode." + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(False) + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(0) + self.top.cmdSetVPPVoltage(12) + self.applyGND(True) + self.applyVCC(True) + + self.__setPins(SCI=0, SDO_en=0, RST_en=1, RST=0) + for i in range(0, 6): + self.__setPins(SCI=0, SDO_en=0, RST_en=1, RST=0) + self.__setPins(SCI=1, SDO_en=0, RST_en=1, RST=0) + self.__setPins(SCI=0, SDO_en=1, SDO=0, RST_en=1, RST=0) + self.top.hostDelay(0.001) + self.__setPins(SDO_en=1, SDO=0, RST_en=0) + self.applyVPP(True) + self.top.hostDelay(0.001) + self.__setPins(SDO_en=0) + self.top.hostDelay(0.01) + + 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 __sendReadEEPROMInstr(self): + self.__sendInstr(SDI=0x03, SII=0x4C) + + def __sendWriteEEPROMInstr(self): + self.__sendInstr(SDI=0x11, SII=0x4C) + + def __sendReadFlashInstr(self): + self.__sendInstr(SDI=0x02, SII=0x4C) + + def __sendWriteFlashInstr(self): + self.__sendInstr(SDI=0x10, SII=0x4C) + + def __sendNOP(self): + self.__sendInstr(SDI=0x00, SII=0x4C) + + def __sendInstr(self, SDI, SII): + self.__setSDI(SDI) + self.__setSII(SII) + 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) + + def __setSDI(self, sdi): + self.top.cmdFPGAWrite(0x13, sdi & 0xFF) + + def __setSII(self, sii): + self.top.cmdFPGAWrite(0x14, sii & 0xFF) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __setPins(self, SCI=0, SDO_en=0, SDO=0, RST_en=0, RST=0): + data = 0 + if SCI: + data |= 1 + if SDO_en: + data |= 2 + if SDO: + data |= 4 + if RST_en: + data |= 8 + if RST: + data |= 16 + 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 __rawSDOState(self): + return bool(self.__getStatusFlags() & self.STAT_SDO) + + 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 __waitHighSDO(self): + for i in range(0, 100): + if self.__rawSDOState(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout waiting for SDO.") + +ChipDescription( + Chip_AtTiny13dip8, + bitfile = "attiny13dip8", + runtimeID = (0x0001, 0x01), + chipVendors = "Atmel", + description = "AtTiny13", + packages = ( ("DIP8", ""), ), +) diff --git a/libtoprammer/chips/attiny26dip20.py b/libtoprammer/chips/attiny26dip20.py new file mode 100644 index 0000000..0faaa63 --- /dev/null +++ b/libtoprammer/chips/attiny26dip20.py @@ -0,0 +1,48 @@ +""" +# TOP2049 Open Source programming suite +# +# Atmel Tiny26 DIP20 support +# +# Copyright (c) 2009-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 atmega_common import * + + +class Chip_ATTiny26DIP20(Chip_ATMega_common): + def __init__(self): + Chip_ATMega_common.__init__(self, + chipPackage = "DIP20", + chipPinVCC = 5, + chipPinsVPP = 10, + chipPinGND = 6, + signature = "\x1E\x91\x09", + flashPageSize = 16, + flashPages = 64, + eepromPageSize = 4, + eepromPages = 32) + +ChipDescription( + Chip_ATTiny26DIP20, + bitfile = "attiny26dip20", + runtimeID = (0x0002, 0x01), + chipVendors = "Atmel", + description = "AtTiny26", + packages = ( ("DIP20", ""), ), + comment = "Special ZIF position", + broken = True +) diff --git a/libtoprammer/chips/generic_sram.py b/libtoprammer/chips/generic_sram.py new file mode 100644 index 0000000..29ba860 --- /dev/null +++ b/libtoprammer/chips/generic_sram.py @@ -0,0 +1,122 @@ +""" +# TOP2049 Open Source programming suite +# +# Generic SRAM chip +# +# Copyright (c) 2011 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_genericSRAM(Chip): + def __init__(self, chipPackage, chipPinVCC, chipPinGND, + VCCVoltage, + nrAddressBits, nrDataBits): + Chip.__init__(self, + chipPackage = chipPackage, + chipPinVCC = chipPinVCC, + chipPinGND = chipPinGND) + self.VCCVoltage = VCCVoltage + self.nrAddressBits = nrAddressBits + self.nrAddressBytes = int(math.ceil((float(self.nrAddressBits) - 0.1) / 8)) + self.nrDataBits = nrDataBits + assert(nrDataBits == 8) + + def erase(self): + self.writeRAM(int2byte(0) * self.__sizeBytes()) + + def test(self): + generic = GenericAlgorithms(self) + generic.simpleTest(self.readRAM, self.writeRAM, + self.__sizeBytes()) + + def readRAM(self): + image = [] + + self.progressMeterInit("Reading SRAM", self.__sizeBytes()) + self.__turnOnChip() + self.__setControlPins(CE=0, OE=0, WE=1) + nrBytes = 0 + for addr in range(0, self.__sizeBytes()): + self.progressMeter(addr) + self.__setAddress(addr) + self.__readData() + nrBytes += 1 + if nrBytes == self.top.getBufferRegSize(): + image.append(self.top.cmdReadBufferReg(nrBytes)) + nrBytes = 0 + image.append(self.top.cmdReadBufferReg(nrBytes)) + self.__setControlPins(CE=1, OE=1, WE=1) + self.progressMeterFinish() + + return b"".join(image) + + def writeRAM(self, image): + if len(image) > self.__sizeBytes(): + self.throwError("Invalid memory image size %d (expected max %d)" %\ + (len(image), self.__sizeBytes())) + + self.progressMeterInit("Writing SRAM", self.__sizeBytes()) + self.__turnOnChip() + self.__setControlPins(CE=0, OE=1, WE=1) + for addr in range(0, len(image)): + self.progressMeter(addr) + self.__setAddress(addr) + self.__writeData(image[addr]) + self.__setControlPins(CE=0, OE=1, WE=0) + self.top.cmdDelay(0.00000007) # Delay at least 70 nsec + self.__setControlPins(CE=0, OE=1, WE=1) + self.__setControlPins(CE=1, OE=1, WE=1) + self.progressMeterFinish() + + def __sizeBytes(self): + return (1 << self.nrAddressBits) + + def __turnOnChip(self): + self.__setControlPins(CE=1, OE=1, WE=1) + self.top.cmdSetVCCVoltage(self.VCCVoltage) + self.applyGND(True) + self.applyVCC(True) + self.lastAddress = None + + def __setControlPins(self, CE=1, OE=1, WE=1): + value = 0 + if CE: + value |= 1 + if OE: + value |= 2 + if WE: + value |= 4 + self.top.cmdFPGAWrite(0x11, value) + + def __writeData(self, data): + data = byte2int(data) + self.top.cmdFPGAWrite(0x10, data) + + def __readData(self): + self.top.cmdFPGARead(0x10) + + def __setAddress(self, addr): + for i in range(0, self.nrAddressBytes): + shift = 8 * i + mask = 0xFF << shift + if self.lastAddress is None or\ + (self.lastAddress & mask) != (addr & mask): + self.top.cmdFPGAWrite(0x12 + i, + (addr & mask) >> shift) + self.lastAddress = addr diff --git a/libtoprammer/chips/hm62256dip28.py b/libtoprammer/chips/hm62256dip28.py new file mode 100644 index 0000000..708c5a9 --- /dev/null +++ b/libtoprammer/chips/hm62256dip28.py @@ -0,0 +1,45 @@ +""" +# TOP2049 Open Source programming suite +# +# HM62256 DIP28 SRAM support +# +# Copyright (c) 2011 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 generic_sram import * + + +class Chip_HM62256DIP28(Chip_genericSRAM): + def __init__(self): + Chip_genericSRAM.__init__(self, + chipPackage = "DIP28", + chipPinVCC = 28, + chipPinGND = 14, + VCCVoltage = 5, + nrAddressBits = 15, + nrDataBits = 8, + ) + +ChipDescription( + Chip_HM62256DIP28, + bitfile = "hm62256dip28", + runtimeID = (0x000A, 0x01), + chipType = ChipDescription.TYPE_SRAM, + chipVendors = "S@Tech", + description = "HM62256 SRAM", + packages = ( ("DIP28", ""), ) +) diff --git a/libtoprammer/chips/m24cxxdip8.py b/libtoprammer/chips/m24cxxdip8.py new file mode 100644 index 0000000..8d3f156 --- /dev/null +++ b/libtoprammer/chips/m24cxxdip8.py @@ -0,0 +1,260 @@ +""" +# TOP2049 Open Source programming suite +# +# M24C16 I2C based serial EEPROM +# +# Copyright (c) 2011 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_m24cXXdip8_common(Chip): + CMD_DEVSEL_READ = 0 + CMD_DEVSEL_WRITE = 1 + CMD_SETADDR = 2 + CMD_DATA_READ = 3 + CMD_DATA_READ_STOP = 4 + CMD_DATA_WRITE = 5 + CMD_DATA_WRITE_STOP = 6 + + def __init__(self, eepromSize): + Chip.__init__(self, + chipPackage = "DIP8", + chipPinVCC = 8, + chipPinGND = 4) + self.eepromSize = eepromSize # in bytes + + def __chipTurnOn(self): + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(5) + self.applyVCC(True) + self.applyVPP(False) + self.applyGND(True) + self.top.cmdEnableZifPullups(True) + + self.currentAddrExt = None + + def erase(self): + self.writeEEPROM("\xFF" * self.eepromSize) + + def readEEPROM(self): + self.__chipTurnOn() + + image = "" + count = 0 + prevAddr = None + self.progressMeterInit("Reading EEPROM", self.eepromSize) + for addr in range(0, self.eepromSize): + self.progressMeter(addr) + if prevAddr is None or (prevAddr & 0xFF00) != (addr & 0xFF00): + self.__setAddress(addr, writeMode=False) + self.__runCommand(self.CMD_DEVSEL_WRITE) + self.__runCommand(self.CMD_SETADDR) + self.__runCommand(self.CMD_DEVSEL_READ) + self.__runCommand(self.CMD_DATA_READ_STOP) + prevAddr = addr + else: + self.__runCommand(self.CMD_DEVSEL_READ) + self.__runCommand(self.CMD_DATA_READ_STOP) + self.__readData() + count += 1 + if count == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(count) + count = 0 + image += self.top.cmdReadBufferReg(count) + self.progressMeterFinish() + + return image + + def writeEEPROM(self, image): + if len(image) > self.eepromSize: + self.throwError("Invalid EEPROM image size %d (expected <=%d)" %\ + (len(image), self.eepromSize)) + self.__chipTurnOn() + + self.progressMeterInit("Writing EEPROM", len(image)) + prevAddr = None + for addr in range(0, len(image)): + self.progressMeter(addr) + self.__setData(byte2int(image[addr])) + if prevAddr is None or (prevAddr & 0xFFF0) != (addr & 0xFFF0): + self.__setAddress(addr, writeMode=True) + self.__runCommand(self.CMD_DEVSEL_WRITE, busyWait=True) + self.__runCommand(self.CMD_SETADDR, busyWait=True) + self.__runCommand(self.CMD_DATA_WRITE, busyWait=True) + prevAddr = addr + else: + if (addr & 0xF) == 0xF: + self.__runCommand(self.CMD_DATA_WRITE_STOP, busyWait=True) + else: + self.__runCommand(self.CMD_DATA_WRITE, busyWait=True) + self.progressMeterFinish() + + def __readData(self): + self.top.cmdFPGARead(0x10) + + def __setData(self, dataByte): + self.top.cmdFPGAWrite(0x12, dataByte & 0xFF) + + def __setAddress(self, address, writeMode): + # Address base + self.top.cmdFPGAWrite(0x11, address & 0xFF) + # Address extension + sizeMask = self.eepromSize - 1 + assert(sizeMask & ~0x7FF == 0) + addrExt = address & 0x700 & sizeMask + if self.currentAddrExt != addrExt: + self.currentAddrExt = addrExt + if sizeMask & 0x0100: + E0 = addrExt & 0x0100 + E0_en = 0 + else: + E0 = 0 + E0_en = 1 + if sizeMask & 0x0200: + E1 = addrExt & 0x0200 + E1_en = 0 + else: + E1 = 0 + E1_en = 1 + if sizeMask & 0x0400: + E2 = addrExt & 0x0400 + E2_en = 0 + else: + E2 = 0 + E2_en = 1 + if writeMode: + WC = 0 + else: + WC = 1 + self.__setControlPins(E0=E0, E0_en=E0_en, + E1=E1, E1_en=E1_en, + E2=E2, E2_en=E2_en, + WC=WC) + + def __runCommand(self, command, busyWait=False): + self.top.cmdFPGAWrite(0x10, command & 0xFF) + if busyWait: + self.__busyWait() + else: + # We do not read busy flags, but wait long enough for + # the operation to finish. This is safe for eeprom read. + self.top.cmdDelay(0.00009) + + def __isBusy(self): + (busy0, busy1) = self.__getStatusFlags() + return busy0 != busy1 + + def __busyWait(self): + for i in range(0, 100): + if not self.__isBusy(): + return + self.top.hostDelay(0.001) + self.throwError("Timeout in busywait.") + + def __getStatusFlags(self): + self.top.cmdFPGARead(0x11) + stat = self.top.cmdReadBufferReg8() + busy0 = bool(stat & 0x01) + busy1 = bool(stat & 0x02) + return (busy0, busy1) + + def __setControlPins(self, E0, E0_en, E1, E1_en, E2, E2_en, WC): + value = 0 + if E0: + value |= (1 << 0) + if E0_en: + value |= (1 << 1) + if E1: + value |= (1 << 2) + if E1_en: + value |= (1 << 3) + if E2: + value |= (1 << 4) + if E2_en: + value |= (1 << 5) + if WC: + value |= (1 << 6) + self.top.cmdFPGAWrite(0x13, value) + +class Chip_m24c01dip8(Chip_m24cXXdip8_common): + def __init__(self): + Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 1 // 8) + +class Chip_m24c02dip8(Chip_m24cXXdip8_common): + def __init__(self): + Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 2 // 8) + +class Chip_m24c04dip8(Chip_m24cXXdip8_common): + def __init__(self): + Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 4 // 8) + +class Chip_m24c08dip8(Chip_m24cXXdip8_common): + def __init__(self): + Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 8 // 8) + +class Chip_m24c16dip8(Chip_m24cXXdip8_common): + def __init__(self): + Chip_m24cXXdip8_common.__init__(self, eepromSize = 1024 * 16 // 8) + +class ChipDescription_m24cXX(ChipDescription): + def __init__(self, chipImplClass, chipID, description): + ChipDescription.__init__(self, + chipImplClass = chipImplClass, + bitfile = "m24c16dip8", + chipID = chipID, + runtimeID = (0x000B, 0x01), + chipType = ChipDescription.TYPE_EEPROM, + chipVendors = "ST", + description = description, + packages = ( + ("DIP8", ""), + ("SO8", "With 1:1 adapter"), + ("TSSOP8", "With 1:1 adapter"), + ), + ) + +ChipDescription_m24cXX( + Chip_m24c01dip8, + chipID = "m24c01dip8", + description = "M24C01 I2C EEPROM", +) + +ChipDescription_m24cXX( + Chip_m24c02dip8, + chipID = "m24c02dip8", + description = "M24C02 I2C EEPROM", +) + +ChipDescription_m24cXX( + Chip_m24c04dip8, + chipID = "m24c04dip8", + description = "M24C04 I2C EEPROM", +) + +ChipDescription_m24cXX( + Chip_m24c08dip8, + chipID = "m24c08dip8", + description = "M24C08 I2C EEPROM", +) + +ChipDescription_m24cXX( + Chip_m24c16dip8, + chipID = "m24c16dip8", + description = "M24C16 I2C EEPROM", +) diff --git a/libtoprammer/chips/m2764a.py b/libtoprammer/chips/m2764a.py new file mode 100644 index 0000000..7eecbb9 --- /dev/null +++ b/libtoprammer/chips/m2764a.py @@ -0,0 +1,173 @@ +""" +# TOP2049 Open Source programming suite +# +# M2764A EPROM programmer +# +# Copyright (c) 2010 Michael Buesch +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" + +from libtoprammer.chip import * + + +class Chip_M2764A(Chip): + PROGCMD_PPULSE = 1 # Perform a P-pulse + + STAT_BUSY = 0x01 # Programmer is running a command + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP28", + chipPinVCC = 28, + chipPinsVPP = 1, + chipPinGND = 14) + + def __initChip(self): + self.applyVCC(False) + self.applyVPP(False) + self.applyGND(False) + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(0) + self.top.cmdSetVPPVoltage(5) + + def readEEPROM(self): + self.__initChip() + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(5) + self.applyVCC(True) + self.applyVPP(True) + self.applyGND(True) + + image = "" + self.progressMeterInit("Reading EPROM", 0x2000) + self.__setEG(E=1, G=1) + byteCount = 0 + for addr in range(0, 0x2000): + self.progressMeter(addr) + self.__readDataToStatusReg(addr) + byteCount += 1 + if byteCount == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(byteCount) + byteCount = 0 + image += self.top.cmdReadBufferReg(byteCount) + self.__setEG(E=1, G=1) + self.progressMeterFinish() + + return image + + def writeEEPROM(self, image): + if len(image) > 0x2000: + self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ + (len(image), 0x2000)) + + self.__initChip() + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(12) + self.applyVCC(True) + self.applyVPP(True) + self.applyGND(True) + + self.progressMeterInit("Writing EPROM", len(image)) + self.__setEG(E=1, G=1) + for addr in range(0, len(image)): + self.progressMeter(addr) + data = byte2int(image[addr]) + if data != 0xFF: + self.__writeData(addr, data) + self.__setEG(E=1, G=1) + self.progressMeterFinish() + + def __readDataToStatusReg(self, addr): + self.__loadAddr(addr) + self.__setEG(E=0, G=0) + self.top.cmdFPGARead(0x10) + + def __writeData(self, addr, data): + self.__setEG(E=0, G=1) + self.__loadAddr(addr) + self.__loadData(data) + self.__loadPPulseLen(1) + self.__runCommandSync(self.PROGCMD_PPULSE) + for i in range(0, 25): + self.__readDataToStatusReg(addr) + stat = self.top.cmdReadBufferReg() + r = byte2int(stat[0]) + if r == data: + break + self.__setEG(E=0, G=1) + self.__runCommandSync(self.PROGCMD_PPULSE) + else: + self.throwError("Failed to program 0x%04X (got 0x%02X, expected 0x%02X)" %\ + (addr, r, data)) + self.__setEG(E=0, G=1) + self.__loadPPulseLen(3 * (i + 1)) + self.__runCommandSync(self.PROGCMD_PPULSE) + + def __loadData(self, data): + self.top.cmdFPGAWrite(0x10, data) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __loadAddrLow(self, addrLow): + self.top.cmdFPGAWrite(0x13, addrLow & 0xFF) + + def __loadAddrHigh(self, addrHigh): + self.top.cmdFPGAWrite(0x14, addrHigh & 0xFF) + + def __loadAddr(self, addr): + self.__loadAddrLow(addr) + self.__loadAddrHigh(addr >> 8) + + def __loadPPulseLen(self, msec): + self.top.cmdFPGAWrite(0x15, msec) + + def __setEG(self, E, G): + data = 0 + if E: + data |= 1 + if G: + data |= 2 + self.top.cmdFPGAWrite(0x16, data) + + def __getStatusFlags(self): + self.top.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, 100): + if not self.__busy(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout in busywait.") + +ChipDescription( + Chip_M2764A, + bitfile = "m2764a", + runtimeID = (0x0006, 0x01), + chipType = ChipDescription.TYPE_EPROM, + description = "M2764A EPROM", + maintainer = None, + packages = ( ("DIP28", ""), ), +) diff --git a/libtoprammer/chips/m8cissp.py b/libtoprammer/chips/m8cissp.py new file mode 100644 index 0000000..975a5ea --- /dev/null +++ b/libtoprammer/chips/m8cissp.py @@ -0,0 +1,457 @@ +""" +# TOP2049 Open Source programming suite +# +# Cypress M8C In System Serial Programmer +# +# Copyright (c) 2010-2011 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 * +import time + + +class Chip_M8C_ISSP(Chip): + ISSPCMD_POR = 1 # Perform a power-on-reset + ISSPCMD_PWROFF = 2 # Turn power off + ISSPCMD_EXEC = 3 # Do an "execute" transfer + + STAT_BUSY0 = 0x01 + STAT_BUSY1 = 0x02 + STAT_ISSPSTATE = 0x1C + STAT_ISSPSTATE_SHIFT = 2 + STAT_SDATA = 0x20 + + STRVEC_INIT1 = ( + "1100101010000000000111", + "0000000000000000000000", + "0000000000000000000000", + "0000000000000000000000", + "0000000000000000000000", + "0000000000000000000000", + "1101111011100010000111", + "1101111101000000000111", + "1101111011100000000111", + "1101111011100010000111", + "1101111111000000100111", + "1101110001000000100111", + "1101110000000000011111", + "1101111011100000000111", + "1001111100000111010111", + "1001111100100000011111", + "1001111101101000000111", + "1001111110000000000111", + "1001111111001010110111", + "1001111110100000001111", + "1001111111100000001111", + "1001111111110000000111", + "1101111011100010000111", + "1101110001000000000111", + "1101111111000000000111", + "1101110000000000000111", + "1101111011100000000111", + "1101111010000000011111", + "1101111010100000000111", + "1101111011000000000111", + "1101111100000000000111", + "1101111100100110000111", + ) + + STRVEC_INIT2 = ( + "1001111101000000000111", + "1101111000000000110111", + "1101111100000000000111", + "1101111111100010010111", + ) + + STRVEC_IDSETUP = ( + "1101111011100010000111", + "1101110000000000010111", + "1101111011100010000111", + "1101111101000000000111", + "1101111011100000000111", + "1101111011100010000111", + "1101111111000000100111", + "1101110001000000100111", + "1101110000000000011111", + "1101111011100000000111", + "1001111100000111010111", + "1001111100100000011111", + "1001111101101000000111", + "1001111110000000000111", + "1001111111001010110111", + "1001111110100000001111", + "1001111111100000001111", + "1001111111110000000111", + "1101111011100010000111", + "1101110001000000000111", + "1101111111000000000111", + "1101110000000000000111", + "1101111011100000000111", + "1101111010000000011111", + "1101111010100000000111", + "1101111011000000000111", + "1101111100000000000111", + "1101111100100110000111", + "1001111101000000000111", + "1101111000000000110111", + "1101111100000000000111", + "1101111111100010010111", + ) + + STRVEC_READBYTE = ( + "101aaaaaaaaZDDDDDDDDZ1", + ) + + STRVEC_WRITEBYTE = ( + "100aaaaaaaadddddddd111", + ) + + STRVEC_ERASEALL = ( + "1001111110000010101111", + "1001111111001010110111", + "1101111011100010000111", + "1101111101000000000111", + "1101111011100000000111", + "1101111011100010000111", + "1101111111000000100111", + "1101110001000000100111", + "1101110000000000011111", + "1101111011100000000111", + "1001111100000111010111", + "1001111100100000011111", + "1001111101101000000111", + "1001111110000000000111", + "1001111111001010110111", + "1001111110100000001111", + "1001111111100000001111", + "1001111111110000000111", + "1101111011100010000111", + "1101110001000000000111", + "1101111111000000000111", + "1101110000000000000111", + "1101111011100000000111", + "1101111010000000011111", + "1101111010100000000111", + "1101111011000000000111", + "1101111100000000000111", + "1101111100100110000111", + "1101111000000000101111", + "1101111100000000000111", + "1101111111100010010111", + ) + + STRVEC_SETBLKNUM = ( + "10011111010dddddddd111", + ) + + STRVEC_READBLK = ( + "1101111011100010000111", + "1101111101000000000111", + "1101111011100000000111", + "1101111011100010000111", + "1101111111000000100111", + "1101110001000000100111", + "1101110000000000011111", + "1101111011100000000111", + "1001111100000111010111", + "1001111100100000011111", + "1001111101101000000111", + "1001111110000000000111", + "1001111111001010110111", + "1001111110100000001111", + "1001111111100000001111", + "1001111111110000000111", + "1101111011100010000111", + "1101110001000000000111", + "1101111111000000000111", + "1101110000000000000111", + "1101111011100000000111", + "1101111010000000011111", + "1101111010100000000111", + "1101111011000000000111", + "1101111100000000000111", + "1101111100100110000111", + "1101111000000000001111", + "1101111100000000000111", + "1101111111100010010111", + ) + + STRVEC_WRITEBLK = ( + "1001111110001010100111", + "1001111111001010110111", + "1101111011100010000111", + "1101111101000000000111", + "1101111011100000000111", + "1101111011100010000111", + "1101111111000000100111", + "1101110001000000100111", + "1101110000000000011111", + "1101111011100000000111", + "1001111100000111010111", + "1001111100100000011111", + "1001111101101000000111", + "1001111110000000000111", + "1001111111001010110111", + "1001111110100000001111", + "1001111111100000001111", + "1001111111110000000111", + "1101111011100010000111", + "1101110001000000000111", + "1101111111000000000111", + "1101110000000000000111", + "1101111011100000000111", + "1101111010000000011111", + "1101111010100000000111", + "1101111011000000000111", + "1101111100000000000111", + "1101111100100110000111", + "1101111000000000010111", + "1101111100000000000111", + "1101111111100010010111", + ) + + STRVEC_READCHKSUM = ( + "10111111001ZDDDDDDDDZ1", + "10111111000ZDDDDDDDDZ1", + ) + + STRVEC_READID = ( + "10111111000ZDDDDDDDDZ1", + "10111111001ZDDDDDDDDZ1", + ) + + def __init__(self): + Chip.__init__(self) +# self.progmemSize = 1024 * 16 + self.progmemSize = 256#XXX + + def readSignature(self): + self.progressMeterInit("Reading chip ID", 0) + self.__powerOnReset() + gotID = self.__readID() + self.progressMeterFinish() + + return int2byte(gotID & 0xFF) + int2byte((gotID >> 8) & 0xFF) + + def erase(self): + self.progressMeterInit("Erasing chip", 0) + self.__powerOnReset() + self.__bitbangStringVectors(self.STRVEC_ERASEALL) + self.__runCommandSync(self.ISSPCMD_EXEC) + self.progressMeterFinish() + + def writeProgmem(self, image): + if len(image) > self.progmemSize or len(image) % 64 != 0: + self.throwError("Invalid program memory image size %d " + "(expected <=%d and multiple of 64)" %\ + (len(image), self.progmemSize)) + + self.progressMeterInit("Writing program memory", len(image)) + self.__powerOnReset() + for blknum in range(0, len(image) // 64): + for i in range(0, 64): + self.progressMeter(blknum * 64 + i) + self.__writeByte(i, byte2int(image[blknum * 64 + i])) + vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum) + self.__bitbangStringVector(vec) + self.__bitbangStringVectors(self.STRVEC_WRITEBLK) + self.__runCommandSync(self.ISSPCMD_EXEC) + self.progressMeterFinish() + + def readProgmem(self): + self.progressMeterInit("Reading program memory", self.progmemSize) + self.__powerOnReset() + assert(self.progmemSize % 64 == 0) + image = [] + for blknum in range(0, self.progmemSize // 64): + vec = self.__stringVectorReplace(self.STRVEC_SETBLKNUM[0], "d", blknum) + self.__bitbangStringVector(vec) + self.__bitbangStringVectors(self.STRVEC_READBLK) + self.__runCommandSync(self.ISSPCMD_EXEC) + for i in range(0, 64): + self.progressMeter(blknum * 64 + i) + image.append(int2byte(self.__readByte(i))) + #FIXME return_code + self.progressMeterFinish() + return b"".join(image) + + def __powerDown(self): + "Turn the power to the device off" + self.printDebug("Powering device down...") + self.__runCommandSync(self.ISSPCMD_PWROFF) + self.top.hostDelay(5) + + def __powerOnReset(self): + "Perform a complete power-on-reset and initialization" + self.top.vcc.setLayoutMask(0) + self.top.vpp.setLayoutMask(0) + self.top.gnd.setLayoutMask(0) + self.top.cmdSetVCCVoltage(5) + self.top.cmdSetVPPVoltage(5) + + self.printDebug("Initializing supply power...") + self.top.gnd.setLayoutPins( (20,) ) + self.top.vcc.setLayoutPins( (21,) ) + +#FIXME when to do exec? + self.__powerDown() + self.printDebug("Performing a power-on-reset...") + self.__uploadStringVector(self.STRVEC_INIT1[0]) + self.__runCommandSync(self.ISSPCMD_POR) + self.printDebug("Sending vector 1...") + self.__bitbangStringVectors(self.STRVEC_INIT1[1:]) +#XXX self.__runCommandSync(self.ISSPCMD_EXEC) + self.printDebug("Sending vector 2...") + self.__bitbangStringVectors(self.STRVEC_INIT2) + self.__runCommandSync(self.ISSPCMD_EXEC) + + def __readID(self): + "Read the silicon ID" + self.__bitbangStringVectors(self.STRVEC_IDSETUP) + self.__runCommandSync(self.ISSPCMD_EXEC) + + low = (self.__bitbangStringVector(self.STRVEC_READID[0]) >> 2) & 0xFF + high = (self.__bitbangStringVector(self.STRVEC_READID[1]) >> 2) & 0xFF + + return low | (high << 8) + + def __readByte(self, address): + vec = self.__stringVectorReplace(self.STRVEC_READBYTE[0], "a", address) + inputData = self.__bitbangStringVector(vec) + return (inputData >> 2) & 0xFF + + def __writeByte(self, address, byte): + vec = self.__stringVectorReplace(self.STRVEC_WRITEBYTE[0], "a", address) + vec = self.__stringVectorReplace(vec, "d", byte) + self.__bitbangStringVector(vec) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x11, command & 0xFF) + + def __runCommandSync(self, command): + self.printDebug("Running synchronous command %d" % command) + self.__loadCommand(command) + self.__busyWait() + + def __setBitbang(self, SDATA, SDATA_in, SCLK, SCLK_z): + value = 0 + if SDATA: + value |= 0x01 + if SDATA_in: + value |= 0x02 + if SCLK: + value |= 0x04 + if SCLK_z: + value |= 0x08 + self.top.cmdFPGAWrite(0x10, value) + + def __getStatusFlags(self): + self.top.cmdFPGARead(0x10) + stat = self.top.cmdReadBufferReg8() + isspState = (stat & self.STAT_ISSPSTATE) >> self.STAT_ISSPSTATE_SHIFT + sdata = bool(stat & self.STAT_SDATA) + isBusy = bool(stat & self.STAT_BUSY0) != bool(stat & self.STAT_BUSY1) + self.printDebug("isspState = 0x%02X, isBusy = %d, busyFlags = 0x%01X, sdata = %d" %\ + (isspState, isBusy, (stat & (self.STAT_BUSY0 | self.STAT_BUSY1)), sdata)) + return (isBusy, sdata, isspState) + + def __busy(self): + (isBusy, sdata, isspState) = self.__getStatusFlags() + return isBusy + + def __getSDATA(self): + (isBusy, sdata, isspState) = self.__getStatusFlags() + return int(sdata) + + def __busyWait(self): + for i in range(0, 200): + if not self.__busy(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout in busywait. Chip not responding?") + + def __stringVectorToBinary(self, vector): + binary = 0 + inputMask = 0 + assert(len(vector) == 22) + bit = len(vector) - 1 + for b in vector: + if b == "1": + binary |= (1 << bit) + elif b == "0": + pass + elif b == "H" or b == "L" or b == "Z" or b == "D": + inputMask |= (1 << bit) + else: + assert(0) + bit -= 1 + return (binary, inputMask) + + def __stringVectorReplace(self, strVec, replace, data): + ret = "" + for i in range(len(strVec) - 1, -1, -1): + b = strVec[i] + if b == replace: + if (data & 1): + ret = "1" + ret + else: + ret = "0" + ret + data >>= 1 + else: + ret = b + ret + return ret + + def __bitbangStringVector(self, strVec): + vectorSize = len(strVec) + (vector, inputMask) = self.__stringVectorToBinary(strVec) + inputData = 0 + self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0) + for i in range(vectorSize - 1, -1, -1): + if inputMask & (1 << i): + self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=1, SCLK_z=0) + self.__setBitbang(SDATA=0, SDATA_in=1, SCLK=0, SCLK_z=0) + self.top.cmdDelay(0.000001) + sdata = self.__getSDATA() + inputData |= (sdata << i) + else: + self.__setBitbang(SDATA=(vector & (1 << i)), SDATA_in=0, + SCLK=1, SCLK_z=0) + self.__setBitbang(SDATA=0, SDATA_in=0, SCLK=0, SCLK_z=0) + self.top.cmdDelay(0.000001) + return inputData + + def __bitbangStringVectors(self, strVecList): + for strVec in strVecList: + self.__bitbangStringVector(strVec) + + def __uploadStringVector(self, strVec): + (vector, inputMask) = self.__stringVectorToBinary(strVec) + assert(inputMask == 0) + self.top.cmdFPGAWrite(0x12, vector & 0xFF) + self.top.cmdFPGAWrite(0x13, (vector >> 8) & 0xFF) + self.top.cmdFPGAWrite(0x14, (vector >> 8) & 0xFF) + +ChipDescription( + Chip_M8C_ISSP, + bitfile = "m8c-issp", + runtimeID = (0x0007, 0x01), + chipVendors = "Cypress", + description = "M8C In System Serial Programmer", + packages = ( ("M8C ISSP header", "Special adapter"), ), + comment = "Special adapter required", + broken = True +) diff --git a/libtoprammer/chips/unitest.py b/libtoprammer/chips/unitest.py new file mode 100644 index 0000000..9f4cf87 --- /dev/null +++ b/libtoprammer/chips/unitest.py @@ -0,0 +1,171 @@ +""" +# TOP2049 Open Source programming suite +# +# Universal device tester +# +# 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_Unitest(Chip): + def __init__(self, chipPackage=None, chipPinVCC=None, chipPinsVPP=None, chipPinGND=None, + VCCVoltage=None, VPPVoltage=None): + Chip.__init__(self, chipPackage=chipPackage, chipPinVCC=chipPinVCC, + chipPinsVPP=chipPinsVPP, chipPinGND=chipPinGND) + self.autogenVCCVoltage = VCCVoltage + self.autogenVPPVoltage = VPPVoltage + + def shutdownChip(self): + self.printDebug("Shutdown chip") + self.reset() + + def reset(self): + self.top.vcc.setLayoutPins( [] ) + self.vccMask = 0 + self.top.vpp.setLayoutPins( [] ) + self.vppMask = 0 + self.top.gnd.setLayoutPins( [] ) + self.gndMask = 0 + self.top.cmdSetVCCVoltage(self.top.vcc.minVoltage()) + self.top.cmdSetVPPVoltage(self.top.vpp.minVoltage()) + self.oscMask = 0 + self.setOutputEnableMask(0) + self.setOutputs(0) + self.setOscMask(0) + self.top.flushCommands() + + def setVCC(self, voltage, layout): + self.vccMask = self.top.vcc.ID2mask(layout) + self.__updateOutEn() + self.top.cmdSetVCCVoltage(voltage) + self.top.vcc.setLayoutID(layout) + self.top.flushCommands() + + def setVPP(self, voltage, layouts): + self.vppMask = 0 + for layout in layouts: + self.vppMask |= self.top.vpp.ID2mask(layout) + self.__updateOutEn() + self.top.cmdSetVPPVoltage(voltage) + self.top.vpp.setLayoutMask(0) # Reset + for layout in layouts: + self.top.vpp.setLayoutID(layout) + self.top.flushCommands() + + def setGND(self, layout): + self.gndMask = self.top.gnd.ID2mask(layout) + self.__updateOutEn() + self.top.gnd.setLayoutID(layout) + self.top.flushCommands() + + # Overloaded layout generator interface. + def applyVCC(self, turnOn): + layoutID = 0 + if turnOn: + (layoutID, layoutMask) = self.generator.getVCCLayout() + self.setVCC(self.autogenVCCVoltage, layoutID) + + # Overloaded layout generator interface. + def applyVPP(self, turnOn, packagePinsToTurnOn=[]): + assert(not packagePinsToTurnOn) # Not supported, yet. + layouts = [] + if turnOn: + layouts = map(lambda (layoutID, layoutMask): layoutID, + self.generator.getVPPLayouts()) + self.setVPP(self.autogenVPPVoltage, layouts) + + # Overloaded layout generator interface. + def applyGND(self, turnOn): + layoutID = 0 + if turnOn: + (layoutID, layoutMask) = self.generator.getGNDLayout() + self.setGND(layoutID) + + def __updateOutEn(self): + mask = self.desiredOutEnMask + mask &= ~self.gndMask + mask &= ~self.vccMask + mask &= ~self.vppMask + mask |= self.oscMask + self.top.cmdFPGAWrite(0x50, mask & 0xFF) + self.top.cmdFPGAWrite(0x51, (mask >> 8) & 0xFF) + self.top.cmdFPGAWrite(0x52, (mask >> 16) & 0xFF) + self.top.cmdFPGAWrite(0x53, (mask >> 24) & 0xFF) + self.top.cmdFPGAWrite(0x54, (mask >> 32) & 0xFF) + self.top.cmdFPGAWrite(0x55, (mask >> 40) & 0xFF) + self.top.flushCommands() + + def setOutputEnableMask(self, mask): + self.desiredOutEnMask = mask + self.__updateOutEn() + + def __updateOut(self): + mask = self.desiredOutMask + mask &= ~self.oscMask + self.top.cmdFPGAWrite(0x70, mask & 0xFF) + self.top.cmdFPGAWrite(0x71, (mask >> 8) & 0xFF) + self.top.cmdFPGAWrite(0x72, (mask >> 16) & 0xFF) + self.top.cmdFPGAWrite(0x73, (mask >> 24) & 0xFF) + self.top.cmdFPGAWrite(0x74, (mask >> 32) & 0xFF) + self.top.cmdFPGAWrite(0x75, (mask >> 40) & 0xFF) + self.top.flushCommands() + + def setOutputs(self, mask): + self.desiredOutMask = mask + self.__updateOut() + + def getInputs(self): + self.top.cmdFPGARead(0x30) + self.top.cmdFPGARead(0x31) + self.top.cmdFPGARead(0x32) + self.top.cmdFPGARead(0x33) + self.top.cmdFPGARead(0x34) + self.top.cmdFPGARead(0x35) + inputs = self.top.cmdReadBufferReg48() + return inputs + + def getOscFreq(self): + return self.top.getOscillatorHz() + + def setOscDivider(self, div): + self.top.cmdFPGAWrite(0x12, div & 0xFF) + self.top.cmdFPGAWrite(0x13, (div >> 8) & 0xFF) + self.top.cmdFPGAWrite(0x14, (div >> 16) & 0xFF) + self.top.cmdFPGAWrite(0x15, (div >> 24) & 0xFF) + self.top.flushCommands() + + def setOscMask(self, mask): + self.oscMask = mask + self.top.cmdFPGAWrite(0x30, mask & 0xFF) + self.top.cmdFPGAWrite(0x31, (mask >> 8) & 0xFF) + self.top.cmdFPGAWrite(0x32, (mask >> 16) & 0xFF) + self.top.cmdFPGAWrite(0x33, (mask >> 24) & 0xFF) + self.top.cmdFPGAWrite(0x34, (mask >> 32) & 0xFF) + self.top.cmdFPGAWrite(0x35, (mask >> 40) & 0xFF) + self.__updateOutEn() + self.__updateOut() + self.top.flushCommands() + +ChipDescription( + Chip_Unitest, + bitfile = "unitest", + runtimeID = (0x0008, 0x01), + chipType = ChipDescription.TYPE_INTERNAL, + description = "Universal device tester", +) diff --git a/libtoprammer/chips/w29ee011dip32.py b/libtoprammer/chips/w29ee011dip32.py new file mode 100644 index 0000000..0948c0f --- /dev/null +++ b/libtoprammer/chips/w29ee011dip32.py @@ -0,0 +1,254 @@ +""" +# TOP2049 Open Source programming suite +# +# Winbond W29EE011 DIP32 +# Winbond W29EE011 PLCC32 (inside 1:1 PLCC32->DIP32 adapter) +# +# 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_w29ee011dip32(Chip): + PROGCMD_WRITEBUF = 1 # Write buffer to chip + + STAT_BUSY = 0x01 # Programmer is running a command + + def __init__(self): + Chip.__init__(self, + chipPackage = "DIP32", + chipPinVCC = 32, + chipPinsVPP = None, + chipPinGND = 16) + + def erase(self): + self.applyVCC(True) + self.applyVPP(True) + self.applyGND(True) + + commands = ( + (0x5555, 0xAA), + (0x2AAA, 0x55), + (0x5555, 0x80), + (0x5555, 0xAA), + (0x2AAA, 0x55), + (0x5555, 0x10), + ) + + self.progressMeterInit("Erasing chip", 0) + self.__setCEOE(CE=0, OE=1) + + self.__resetBufferPointers() + self.__swDataProtect(False) + self.__runCommandSync(self.PROGCMD_WRITEBUF) + self.top.hostDelay(0.05) + self.__resetBufferPointers() + for command in commands: + self.__appendJEDEC(command[0], command[1]) + self.__runCommandSync(self.PROGCMD_WRITEBUF) + self.top.hostDelay(0.05) + + self.__setCEOE(CE=1, OE=1) + self.progressMeterFinish() + + def readEEPROM(self): + self.applyVCC(True) + self.applyVPP(True) + self.applyGND(True) + + self.progressMeterInit("Reading EEPROM", 0x20000) + self.__setCEOE(CE=0, OE=0) + image = self.__readRange(0, 0x20000, progress=True) + self.__setCEOE(CE=1, OE=1) + self.progressMeterFinish() + + return image + + def __readRange(self, baseAddress, size, progress=False): + image = "" + byteCount = 0 + prevAddr = baseAddress + self.__loadReadAddrLo(baseAddress) + self.__loadReadAddrMed(baseAddress >> 8) + self.__loadReadAddrHi(baseAddress >> 16) + for offset in range(0, size): + addr = baseAddress + offset + if progress: + self.progressMeter(addr) + if (addr & 0xFF) != (prevAddr & 0xFF): + self.__loadReadAddrLo(addr) + if (addr & 0xFF00) != (prevAddr & 0xFF00): + self.__loadReadAddrMed(addr >> 8) + if (addr & 0xFF0000) != (prevAddr & 0xFF0000): + self.__loadReadAddrHi(addr >> 16) + prevAddr = addr + self.top.cmdFPGARead(0x10) + byteCount += 1 + if byteCount == self.top.getBufferRegSize(): + image += self.top.cmdReadBufferReg(byteCount) + byteCount = 0 + image += self.top.cmdReadBufferReg(byteCount) + return image + + def writeEEPROM(self, image): + if len(image) > 0x20000: + self.throwError("Invalid EPROM image size %d (expected <=%d)" %\ + (len(image), 0x20000)) + + self.applyVCC(True) + self.applyVPP(True) + self.applyGND(True) + + self.progressMeterInit("Writing EEPROM", len(image)) + self.__setCEOE(CE=0, OE=1) + for addr in range(0, len(image), 128): + self.progressMeter(addr) + pagelen = min(128, len(image) - addr) + page = image[addr:addr+pagelen] + self.__writePage(addr, page) + self.__setCEOE(CE=1, OE=1) + self.progressMeterFinish() + + def __swDataProtect(self, enable): + if enable: + jedecCommands = ( + (0x5555, 0xAA), + (0x2AAA, 0x55), + (0x5555, 0xA0), + ) + else: + jedecCommands = ( + (0x5555, 0xAA), + (0x2AAA, 0x55), + (0x5555, 0x80), + (0x5555, 0xAA), + (0x2AAA, 0x55), + (0x5555, 0x20), + ) + for command in jedecCommands: + self.__appendJEDEC(command[0], command[1]) + + def __writePage(self, pageAddress, pageData): + for t in range(0, 15): + self.__resetBufferPointers() + self.__swDataProtect(True) + assert(len(pageData) <= 128) + for byte in pageData: + self.__writeBufAppend(byte2int(byte)) + self.__loadWriteAddr(pageAddress) + self.__runCommandSync(self.PROGCMD_WRITEBUF) + self.top.hostDelay(0.01) + # Verify + self.__setCEOE(CE=0, OE=0) + verifyImage = self.__readRange(pageAddress, len(pageData)) + self.__setCEOE(CE=0, OE=1) + if verifyImage == pageData: + break + self.top.hostDelay(0.1) + else: + self.throwError("Verify error on page write at address 0x%05X" % pageAddress) + + def __writeBufAppend(self, byte): + # This also auto-increments the write buffer pointer + self.top.cmdFPGAWrite(0x10, byte & 0xFF) + + def __resetBufferPointers(self): + self.top.cmdFPGAWrite(0x13, 0) + + def __loadCommand(self, command): + self.top.cmdFPGAWrite(0x12, command & 0xFF) + + def __runCommandSync(self, command): + self.__loadCommand(command) + self.__busyWait() + + def __loadWriteAddr(self, addr): + self.__loadWriteAddrLo(addr) + self.__loadWriteAddrMed(addr >> 8) + self.__loadWriteAddrHi(addr >> 16) + + def __loadWriteAddrLo(self, addrLo): + self.top.cmdFPGAWrite(0x14, addrLo & 0xFF) + + def __loadWriteAddrMed(self, addrMed): + self.top.cmdFPGAWrite(0x15, addrMed & 0xFF) + + def __loadWriteAddrHi(self, addrHi): + self.top.cmdFPGAWrite(0x16, addrHi & 0xFF) + + def __loadReadAddrLo(self, addrLo): + self.top.cmdFPGAWrite(0x17, addrLo & 0xFF) + + def __loadReadAddrMed(self, addrMed): + self.top.cmdFPGAWrite(0x18, addrMed & 0xFF) + + def __loadReadAddrHi(self, addrHi): + self.top.cmdFPGAWrite(0x19, addrHi & 0xFF) + + def __setCEOE(self, CE, OE): + data = 0 + if CE: + data |= 0x01 + if OE: + data |= 0x02 + self.top.cmdFPGAWrite(0x1A, data) + + def __appendJEDEC(self, addr, data): + self.__loadJEDECAddrLo(addr) + self.__loadJEDECAddrMed(addr >> 8) + self.__loadJEDECAddrHi(addr >> 16) + self.__loadJEDECData(data) + + def __loadJEDECAddrLo(self, addrLo): + self.top.cmdFPGAWrite(0x1B, addrLo & 0xFF) + + def __loadJEDECAddrMed(self, addrMed): + self.top.cmdFPGAWrite(0x1C, addrMed & 0xFF) + + def __loadJEDECAddrHi(self, addrHi): + self.top.cmdFPGAWrite(0x1D, addrHi & 0xFF) + + def __loadJEDECData(self, data): + # This also auto-increments the JEDEC buffer pointer + self.top.cmdFPGAWrite(0x1E, data & 0xFF) + + 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, 100): + if not self.__busy(): + return + self.top.hostDelay(0.01) + self.throwError("Timeout in busywait.") + +ChipDescription( + Chip_w29ee011dip32, + bitfile = "w29ee011dip32", + runtimeID = (0x0009, 0x01), + chipType = ChipDescription.TYPE_EEPROM, + chipVendors = "Winbond", + description = "W29EE011 EEPROM", + packages = ( ("DIP32", ""), ("PLCC32", "Use 1:1 PLCC32->DIP32 adapter"), ), + broken = True, +) diff --git a/libtoprammer/layout_generator.py b/libtoprammer/layout_generator.py index bda431a..9d7be1a 100644 --- a/libtoprammer/layout_generator.py +++ b/libtoprammer/layout_generator.py @@ -21,7 +21,7 @@ """ from util import * -from top_xxxx import * +from top_devices import * class LayoutGenerator: diff --git a/libtoprammer/top_devices.py b/libtoprammer/top_devices.py new file mode 100644 index 0000000..39526dd --- /dev/null +++ b/libtoprammer/top_devices.py @@ -0,0 +1,6 @@ +# Import programmer specific stuff + +# TOP2049 specific stuff +import top2049.vcc_layouts +import top2049.vpp_layouts +import top2049.gnd_layouts diff --git a/libtoprammer/top_xxxx.py b/libtoprammer/top_xxxx.py deleted file mode 100644 index 39526dd..0000000 --- a/libtoprammer/top_xxxx.py +++ /dev/null @@ -1,6 +0,0 @@ -# Import programmer specific stuff - -# TOP2049 specific stuff -import top2049.vcc_layouts -import top2049.vpp_layouts -import top2049.gnd_layouts diff --git a/libtoprammer/toprammer_main.py b/libtoprammer/toprammer_main.py index 7b0e352..0a0cc3d 100644 --- a/libtoprammer/toprammer_main.py +++ b/libtoprammer/toprammer_main.py @@ -43,8 +43,8 @@ except (ImportError), e: print "Python USB support module not found. Please install python-usb." sys.exit(1) -from top_xxxx import * -from chip_xxxx import * +from top_devices import * +from chips import * from user_interface import * diff --git a/setup.py b/setup.py index d927a7f..d728e31 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name = "toprammer", author = "Michael Buesch", author_email = "m@bues.ch", url = "http://bues.ch/cms/hacking/toprammer.html", - packages = [ "libtoprammer", "libtoprammer/top2049", ], + packages = [ "libtoprammer", "libtoprammer/top2049", "libtoprammer/chips" ], package_data = { "libtoprammer" : [ "bit/*.bit", "icons/*.png", ], }, scripts = [ "toprammer", "toprammer-gui", "toprammer-layout", ], ) -- cgit v1.2.3