+++ /dev/null
-#!/usr/bin/env python
-# GoodFET Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys, time, string, cStringIO, struct, glob, serial, os;
-
-
-class GoodFET:
- """GoodFET Client Library"""
-
- GLITCHAPP=0x71;
-
- def __init__(self, *args, **kargs):
- self.data=[0];
- def timeout(self):
- print "timeout\n";
- def serInit(self, port=None):
- """Open the serial port"""
-
- if port is None and os.environ.get("GOODFET")!=None:
- glob_list = glob.glob(os.environ.get("GOODFET"));
- if len(glob_list) > 0:
- port = glob_list[0];
- if port is None:
- glob_list = glob.glob("/dev/tty.usbserial*");
- if len(glob_list) > 0:
- port = glob_list[0];
- if port is None:
- glob_list = glob.glob("/dev/ttyUSB*");
- if len(glob_list) > 0:
- port = glob_list[0];
-
- self.serialport = serial.Serial(
- port,
- #9600,
- 115200,
- parity = serial.PARITY_NONE
- )
-
- #This might cause problems, but it makes failure graceful.
- #self.serialport._timeout = 5;
-
- #Explicitly set RTS and DTR to halt board.
- self.serialport.setRTS(1);
- self.serialport.setDTR(1);
- #Drop DTR, which is !RST, low to begin the app.
- self.serialport.setDTR(0);
- self.serialport.flushInput()
- self.serialport.flushOutput()
-
- #Read and handle the initial command.
- #time.sleep(1);
- self.readcmd(); #Read the first command.
- if(self.verb!=0x7F):
- print "Verb %02x is wrong. Incorrect firmware?" % self.verb;
- #print "Connected."
- def getbuffer(self,size=0x1c00):
- writecmd(0,0xC2,[size&0xFF,(size>>16)&0xFF]);
- print "Got %02x%02x buffer size." % (self.data[1],self.data[0]);
- def writecmd(self, app, verb, count=0, data=[]):
- """Write a command and some data to the GoodFET."""
- self.serialport.write(chr(app));
- self.serialport.write(chr(verb));
-
- #if data!=None:
- # count=len(data); #Initial count ignored.
-
- #print "TX %02x %02x %04x" % (app,verb,count);
-
- #little endian 16-bit length
- self.serialport.write(chr(count&0xFF));
- self.serialport.write(chr(count>>8));
-
- #print "count=%02x, len(data)=%04x" % (count,len(data));
-
- if count!=0:
- if(isinstance(data,list)):
- for i in range(0,count):
- #print "Converting %02x at %i" % (data[i],i)
- data[i]=chr(data[i]);
- #print type(data);
- outstr=''.join(data);
- self.serialport.write(outstr);
- if not self.besilent:
- self.readcmd();
-
- besilent=0;
- app=0;
- verb=0;
- count=0;
- data="";
-
- def readcmd(self):
- """Read a reply from the GoodFET."""
- while 1:
- #print "Reading...";
- self.app=ord(self.serialport.read(1));
- #print "APP=%2x" % self.app;
- self.verb=ord(self.serialport.read(1));
- #print "VERB=%02x" % self.verb;
- self.count=(
- ord(self.serialport.read(1))
- +(ord(self.serialport.read(1))<<8)
- );
-
- #Debugging string; print, but wait.
- if self.app==0xFF and self.verb==0xFF:
- print "# DEBUG %s" % self.serialport.read(self.count);
- sys.stdout.flush();
- else:
- self.data=self.serialport.read(self.count);
- return self.data;
- #Glitching stuff.
- def glitchApp(self,app):
- """Glitch into a device by its application."""
- self.data=[app&0xff];
- self.writecmd(self.GLITCHAPP,0x80,1,self.data);
- #return ord(self.data[0]);
- def glitchVerb(self,app,verb,data):
- """Glitch during a transaction."""
- if data==None: data=[];
- self.data=[app&0xff, verb&0xFF]+data;
- self.writecmd(self.GLITCHAPP,0x81,len(self.data),self.data);
- #return ord(self.data[0]);
- def glitchstart(self):
- """Glitch into the AVR application."""
- self.glitchVerb(self.APP,0x20,None);
- def glitchstarttime(self):
- """Measure the timer of the START verb."""
- return self.glitchTime(self.APP,0x20,None);
- def glitchTime(self,app,verb,data):
- """Time the execution of a verb."""
- if data==None: data=[];
- self.data=[app&0xff, verb&0xFF]+data;
- self.writecmd(self.GLITCHAPP,0x82,len(self.data),self.data);
- return ord(self.data[0])+(ord(self.data[1])<<8);
- def glitchVoltages(self,low=0x0880, high=0x0fff):
- """Set glitching voltages. (0x0fff is max.)"""
- self.data=[low&0xff, (low>>8)&0xff,
- high&0xff, (high>>8)&0xff];
- self.writecmd(self.GLITCHAPP,0x90,4,self.data);
- #return ord(self.data[0]);
- def glitchRate(self,count=0x0800):
- """Set glitching count period."""
- self.data=[count&0xff, (count>>8)&0xff];
- self.writecmd(self.GLITCHAPP,0x91,2,
- self.data);
- #return ord(self.data[0]);
-
-
- #Monitor stuff
- def silent(self,s=0):
- """Transmissions halted when 1."""
- self.besilent=s;
- print "besilent is %i" % self.besilent;
- self.writecmd(0,0xB0,1,[s]);
-
- def out(self,byte):
- """Write a byte to P5OUT."""
- self.writecmd(0,0xA1,1,[byte]);
- def dir(self,byte):
- """Write a byte to P5DIR."""
- self.writecmd(0,0xA0,1,[byte]);
- def call(self,adr):
- """Call to an address."""
- self.writecmd(0,0x30,2,
- [adr&0xFF,(adr>>8)&0xFF]);
- def execute(self,code):
- """Execute supplied code."""
- self.writecmd(0,0x31,2,#len(code),
- code);
- def peekbyte(self,address):
- """Read a byte of memory from the monitor."""
- self.data=[address&0xff,address>>8];
- self.writecmd(0,0x02,2,self.data);
- #self.readcmd();
- return ord(self.data[0]);
- def peekword(self,address):
- """Read a word of memory from the monitor."""
- return self.peekbyte(address)+(self.peekbyte(address+1)<<8);
- def pokebyte(self,address,value):
- """Set a byte of memory by the monitor."""
- self.data=[address&0xff,address>>8,value];
- self.writecmd(0,0x03,3,self.data);
- return ord(self.data[0]);
- def dumpmem(self,begin,end):
- i=begin;
- while i<end:
- print "%04x %04x" % (i, self.peekword(i));
- i+=2;
- def monitor_ram_pattern(self):
- """Overwrite all of RAM with 0xBEEF."""
- self.writecmd(0,0x90,0,self.data);
- return;
- def monitor_ram_depth(self):
- """Determine how many bytes of RAM are unused by looking for 0xBEEF.."""
- self.writecmd(0,0x91,0,self.data);
- return ord(self.data[0])+(ord(self.data[1])<<8);
-
- #Baud rates.
- baudrates=[115200,
- 9600,
- 19200,
- 38400,
- 57600,
- 115200];
- def setBaud(self,baud):
- """Change the baud rate. TODO fix this."""
- rates=self.baudrates;
- self.data=[baud];
- print "Changing FET baud."
- self.serialport.write(chr(0x00));
- self.serialport.write(chr(0x80));
- self.serialport.write(chr(1));
- self.serialport.write(chr(baud));
-
- print "Changed host baud."
- self.serialport.setBaudrate(rates[baud]);
- time.sleep(1);
- self.serialport.flushInput()
- self.serialport.flushOutput()
-
- print "Baud is now %i." % rates[baud];
- return;
- def readbyte(self):
- return ord(self.serialport.read(1));
- def findbaud(self):
- for r in self.baudrates:
- print "\nTrying %i" % r;
- self.serialport.setBaudrate(r);
- #time.sleep(1);
- self.serialport.flushInput()
- self.serialport.flushOutput()
-
- for i in range(1,10):
- self.readbyte();
-
- print "Read %02x %02x %02x %02x" % (
- self.readbyte(),self.readbyte(),self.readbyte(),self.readbyte());
- def monitortest(self):
- """Self-test several functions through the monitor."""
- print "Performing monitor self-test.";
-
- if self.peekword(0x0c00)!=0x0c04 and self.peekword(0x0c00)!=0x0c06:
- print "ERROR Fetched wrong value from 0x0c04.";
- self.pokebyte(0x0021,0); #Drop LED
- if self.peekbyte(0x0021)!=0:
- print "ERROR, P1OUT not cleared.";
- self.pokebyte(0x0021,1); #Light LED
-
- print "Self-test complete.";
-
-
- # The following functions ought to be implemented in
- # every client.
-
- def infostring(self):
- a=self.peekbyte(0xff0);
- b=self.peekbyte(0xff1);
- return "%02x%02x" % (a,b);
- def lock(self):
- print "Locking Unsupported.";
- def erase(self):
- print "Erasure Unsupported.";
- def setup(self):
- return;
- def start(self):
- return;
- def test(self):
- return;
- def status(self):
- return;
- def flash(self,file):
- """Flash an intel hex file to code memory."""
- print "Flash not implemented.";
- def peek32(self,address, memory="vn"):
- return (self.peek16(address,memory)+
- (self.peek16(address+2,memory)<<16));
- def peek16(self,address, memory="vn"):
- return (self.peek8(address,memory)+
- (self.peek8(address+1,memory)<<8));
- def peek8(self,address, memory="vn"):
- return 0xde;
--- /dev/null
+#!/usr/bin/env python
+# GoodFET Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+
+class GoodFET:
+ """GoodFET Client Library"""
+
+ GLITCHAPP=0x71;
+
+ def __init__(self, *args, **kargs):
+ self.data=[0];
+
+ def getConsole(self):
+ from GoodFETConsole import GoodFETConsole;
+ return GoodFETConsole(self);
+ def timeout(self):
+ print "timeout\n";
+ def serInit(self, port=None):
+ """Open the serial port"""
+
+ if port is None and os.environ.get("GOODFET")!=None:
+ glob_list = glob.glob(os.environ.get("GOODFET"));
+ if len(glob_list) > 0:
+ port = glob_list[0];
+ if port is None:
+ glob_list = glob.glob("/dev/tty.usbserial*");
+ if len(glob_list) > 0:
+ port = glob_list[0];
+ if port is None:
+ glob_list = glob.glob("/dev/ttyUSB*");
+ if len(glob_list) > 0:
+ port = glob_list[0];
+
+ self.serialport = serial.Serial(
+ port,
+ #9600,
+ 115200,
+ parity = serial.PARITY_NONE
+ )
+
+ #This might cause problems, but it makes failure graceful.
+ #self.serialport._timeout = 5;
+
+ #Explicitly set RTS and DTR to halt board.
+ self.serialport.setRTS(1);
+ self.serialport.setDTR(1);
+ #Drop DTR, which is !RST, low to begin the app.
+ self.serialport.setDTR(0);
+ self.serialport.flushInput()
+ self.serialport.flushOutput()
+
+ #Read and handle the initial command.
+ #time.sleep(1);
+ self.readcmd(); #Read the first command.
+ if(self.verb!=0x7F):
+ print "Verb %02x is wrong. Incorrect firmware?" % self.verb;
+ #print "Connected."
+ def getbuffer(self,size=0x1c00):
+ writecmd(0,0xC2,[size&0xFF,(size>>16)&0xFF]);
+ print "Got %02x%02x buffer size." % (self.data[1],self.data[0]);
+ def writecmd(self, app, verb, count=0, data=[]):
+ """Write a command and some data to the GoodFET."""
+ self.serialport.write(chr(app));
+ self.serialport.write(chr(verb));
+
+ #if data!=None:
+ # count=len(data); #Initial count ignored.
+
+ #print "TX %02x %02x %04x" % (app,verb,count);
+
+ #little endian 16-bit length
+ self.serialport.write(chr(count&0xFF));
+ self.serialport.write(chr(count>>8));
+
+ #print "count=%02x, len(data)=%04x" % (count,len(data));
+
+ if count!=0:
+ if(isinstance(data,list)):
+ for i in range(0,count):
+ #print "Converting %02x at %i" % (data[i],i)
+ data[i]=chr(data[i]);
+ #print type(data);
+ outstr=''.join(data);
+ self.serialport.write(outstr);
+ if not self.besilent:
+ self.readcmd();
+
+ besilent=0;
+ app=0;
+ verb=0;
+ count=0;
+ data="";
+
+ def readcmd(self):
+ """Read a reply from the GoodFET."""
+ while 1:
+ #print "Reading...";
+ self.app=ord(self.serialport.read(1));
+ #print "APP=%2x" % self.app;
+ self.verb=ord(self.serialport.read(1));
+ #print "VERB=%02x" % self.verb;
+ self.count=(
+ ord(self.serialport.read(1))
+ +(ord(self.serialport.read(1))<<8)
+ );
+
+ #Debugging string; print, but wait.
+ if self.app==0xFF and self.verb==0xFF:
+ print "# DEBUG %s" % self.serialport.read(self.count);
+ sys.stdout.flush();
+ else:
+ self.data=self.serialport.read(self.count);
+ return self.data;
+ #Glitching stuff.
+ def glitchApp(self,app):
+ """Glitch into a device by its application."""
+ self.data=[app&0xff];
+ self.writecmd(self.GLITCHAPP,0x80,1,self.data);
+ #return ord(self.data[0]);
+ def glitchVerb(self,app,verb,data):
+ """Glitch during a transaction."""
+ if data==None: data=[];
+ self.data=[app&0xff, verb&0xFF]+data;
+ self.writecmd(self.GLITCHAPP,0x81,len(self.data),self.data);
+ #return ord(self.data[0]);
+ def glitchstart(self):
+ """Glitch into the AVR application."""
+ self.glitchVerb(self.APP,0x20,None);
+ def glitchstarttime(self):
+ """Measure the timer of the START verb."""
+ return self.glitchTime(self.APP,0x20,None);
+ def glitchTime(self,app,verb,data):
+ """Time the execution of a verb."""
+ if data==None: data=[];
+ self.data=[app&0xff, verb&0xFF]+data;
+ self.writecmd(self.GLITCHAPP,0x82,len(self.data),self.data);
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+ def glitchVoltages(self,low=0x0880, high=0x0fff):
+ """Set glitching voltages. (0x0fff is max.)"""
+ self.data=[low&0xff, (low>>8)&0xff,
+ high&0xff, (high>>8)&0xff];
+ self.writecmd(self.GLITCHAPP,0x90,4,self.data);
+ #return ord(self.data[0]);
+ def glitchRate(self,count=0x0800):
+ """Set glitching count period."""
+ self.data=[count&0xff, (count>>8)&0xff];
+ self.writecmd(self.GLITCHAPP,0x91,2,
+ self.data);
+ #return ord(self.data[0]);
+
+
+ #Monitor stuff
+ def silent(self,s=0):
+ """Transmissions halted when 1."""
+ self.besilent=s;
+ print "besilent is %i" % self.besilent;
+ self.writecmd(0,0xB0,1,[s]);
+
+ def out(self,byte):
+ """Write a byte to P5OUT."""
+ self.writecmd(0,0xA1,1,[byte]);
+ def dir(self,byte):
+ """Write a byte to P5DIR."""
+ self.writecmd(0,0xA0,1,[byte]);
+ def call(self,adr):
+ """Call to an address."""
+ self.writecmd(0,0x30,2,
+ [adr&0xFF,(adr>>8)&0xFF]);
+ def execute(self,code):
+ """Execute supplied code."""
+ self.writecmd(0,0x31,2,#len(code),
+ code);
+ def peekbyte(self,address):
+ """Read a byte of memory from the monitor."""
+ self.data=[address&0xff,address>>8];
+ self.writecmd(0,0x02,2,self.data);
+ #self.readcmd();
+ return ord(self.data[0]);
+ def peekword(self,address):
+ """Read a word of memory from the monitor."""
+ return self.peekbyte(address)+(self.peekbyte(address+1)<<8);
+ def pokebyte(self,address,value):
+ """Set a byte of memory by the monitor."""
+ self.data=[address&0xff,address>>8,value];
+ self.writecmd(0,0x03,3,self.data);
+ return ord(self.data[0]);
+ def dumpmem(self,begin,end):
+ i=begin;
+ while i<end:
+ print "%04x %04x" % (i, self.peekword(i));
+ i+=2;
+ def monitor_ram_pattern(self):
+ """Overwrite all of RAM with 0xBEEF."""
+ self.writecmd(0,0x90,0,self.data);
+ return;
+ def monitor_ram_depth(self):
+ """Determine how many bytes of RAM are unused by looking for 0xBEEF.."""
+ self.writecmd(0,0x91,0,self.data);
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+
+ #Baud rates.
+ baudrates=[115200,
+ 9600,
+ 19200,
+ 38400,
+ 57600,
+ 115200];
+ def setBaud(self,baud):
+ """Change the baud rate. TODO fix this."""
+ rates=self.baudrates;
+ self.data=[baud];
+ print "Changing FET baud."
+ self.serialport.write(chr(0x00));
+ self.serialport.write(chr(0x80));
+ self.serialport.write(chr(1));
+ self.serialport.write(chr(baud));
+
+ print "Changed host baud."
+ self.serialport.setBaudrate(rates[baud]);
+ time.sleep(1);
+ self.serialport.flushInput()
+ self.serialport.flushOutput()
+
+ print "Baud is now %i." % rates[baud];
+ return;
+ def readbyte(self):
+ return ord(self.serialport.read(1));
+ def findbaud(self):
+ for r in self.baudrates:
+ print "\nTrying %i" % r;
+ self.serialport.setBaudrate(r);
+ #time.sleep(1);
+ self.serialport.flushInput()
+ self.serialport.flushOutput()
+
+ for i in range(1,10):
+ self.readbyte();
+
+ print "Read %02x %02x %02x %02x" % (
+ self.readbyte(),self.readbyte(),self.readbyte(),self.readbyte());
+ def monitortest(self):
+ """Self-test several functions through the monitor."""
+ print "Performing monitor self-test.";
+
+ if self.peekword(0x0c00)!=0x0c04 and self.peekword(0x0c00)!=0x0c06:
+ print "ERROR Fetched wrong value from 0x0c04.";
+ self.pokebyte(0x0021,0); #Drop LED
+ if self.peekbyte(0x0021)!=0:
+ print "ERROR, P1OUT not cleared.";
+ self.pokebyte(0x0021,1); #Light LED
+
+ print "Self-test complete.";
+
+
+ # The following functions ought to be implemented in
+ # every client.
+
+ def infostring(self):
+ a=self.peekbyte(0xff0);
+ b=self.peekbyte(0xff1);
+ return "%02x%02x" % (a,b);
+ def lock(self):
+ print "Locking Unsupported.";
+ def erase(self):
+ print "Erasure Unsupported.";
+ def setup(self):
+ return;
+ def start(self):
+ return;
+ def test(self):
+ return;
+ def status(self):
+ return;
+ def flash(self,file):
+ """Flash an intel hex file to code memory."""
+ print "Flash not implemented.";
+ def peek32(self,address, memory="vn"):
+ return (self.peek16(address,memory)+
+ (self.peek16(address+2,memory)<<16));
+ def peek16(self,address, memory="vn"):
+ return (self.peek8(address,memory)+
+ (self.peek8(address+1,memory)<<8));
+ def peek8(self,address, memory="vn"):
+ return 0xde;
--- /dev/null
+#!/usr/bin/env python
+# GoodFET SPI and SPIFlash Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+from GoodFET import GoodFET;
+
+class GoodFETAVR(GoodFET):
+ AVRAPP=0x32;
+ APP=AVRAPP;
+ AVRVendors={0x1E: "Atmel",
+ 0x00: "Locked",
+ };
+
+ #List from avr910.asm and other sources.
+ #More devices at http://avr.fenceline.de/device_data.html
+ AVRDevices={
+ 0x9003: "tiny10",
+ 0x9004: "tiny11",
+ 0x9005: "tiny12",
+ 0x9006: "tiny15",
+ 0x9007: "tiny13",
+ 0x9108: "tiny25",
+ 0x930B: "tiny85",
+ 0x9206: "tiny45",
+
+ 0x9001: "S1200",
+
+ 0x9101: "S1213",
+ 0x9102: "S2323",
+ 0x9105: "S2333",
+ 0x9103: "S2343",
+
+ 0x9201: "S4414",
+ 0x9203: "S4433",
+ 0x9202: "S4434",
+
+ 0x9301: "S8515",
+ 0x9303: "S8535",
+
+ 0x9305: "mega83",
+ 0x930a: "mega88",
+ 0x9701: "mega103",
+ 0x9401: "mega161",
+ 0x9402: "mega163",
+ 0x9406: "mega168",
+
+ 0x950f: "mega328",
+ 0x950d: "mega325",
+ 0x9508: "mega32"
+ };
+
+ def setup(self):
+ """Move the FET into the AVR application."""
+ self.writecmd(self.AVRAPP,0x10,0,self.data); #SPI/SETUP
+
+ def trans(self,data):
+ """Exchange data by AVR.
+ Input should probably be 4 bytes."""
+ self.data=data;
+ self.writecmd(self.AVRAPP,0x00,len(data),data);
+ return self.data;
+
+ def start(self):
+ """Start the connection."""
+ self.writecmd(self.AVRAPP,0x20,0,None);
+ def forcestart(self):
+ """Forcibly start a connection."""
+
+ for i in range(0x880,0xfff):
+ #self.glitchVoltages(0x880, i);
+ self.start();
+ bits=self.lockbits();
+ print "At %04x, Lockbits: %02x" % (i,bits);
+ if(bits==0xFF): return;
+ def erase(self):
+ """Erase the target chip."""
+ self.writecmd(self.AVRAPP,0xF0,0,None);
+ def lockbits(self):
+ """Read the target's lockbits."""
+ self.writecmd(self.AVRAPP,0x82,0,None);
+ return ord(self.data[0]);
+ def setlockbits(self,bits=0x00):
+ """Read the target's lockbits."""
+ self.writecmd(self.AVRAPP,0x92,1,[bits]);
+ return self.lockbits();
+
+ def eeprompeek(self, adr):
+ """Read a byte of the target's EEPROM."""
+ self.writecmd(self.AVRAPP,0x81 ,2,
+ [ (adr&0xFF), (adr>>8)]
+ );#little-endian address
+ return ord(self.data[0]);
+ def flashpeek(self, adr):
+ """Read a byte of the target's EEPROM."""
+ self.writecmd(self.AVRAPP,0x02 ,2,
+ [ (adr&0xFF), (adr>>8)]
+ );#little-endian address
+ return ord(self.data[0]);
+ def flashpeekblock(self, adr):
+ """Read a byte of the target's EEPROM."""
+ self.writecmd(self.AVRAPP,0x02 ,4,
+ [ (adr&0xFF), (adr>>8) &0xFF, 0x80, 0x00]
+ );
+ return self.data;
+
+ def eeprompoke(self, adr, val):
+ """Write a byte of the target's EEPROM."""
+ self.writecmd(self.AVRAPP,0x91 ,3,
+ [ (adr&0xFF), (adr>>8), val]
+ );#little-endian address
+ return ord(self.data[0]);
+
+ def identstr(self):
+ """Return an identifying string."""
+ self.writecmd(self.AVRAPP,0x83,0, None);
+ vendor=self.AVRVendors.get(ord(self.data[0]));
+ deviceid=(ord(self.data[1])<<8)+ord(self.data[2]);
+ device=self.AVRDevices.get(deviceid);
+
+ #Return hex if device is unknown.
+ #They are similar enough that it needn't be known.
+ if device==None:
+ device=("0x%04x" % deviceid);
+
+ return "%s %s" % (vendor,device);
--- /dev/null
+#!/usr/bin/env python
+# GoodFET Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys;
+import binascii;
+
+from GoodFET import GoodFET;
+from intelhex import IntelHex;
+
+import xml.dom.minidom;
+
+class GoodFETCC(GoodFET):
+ """A GoodFET variant for use with Chipcon 8051 Zigbee SoC."""
+ APP=0x30;
+ smartrfpath="/opt/smartrf7";
+ def SRF_chipdom(self,chip="cc1110", doc="register_definition.xml"):
+ fn="%s/config/xml/%s/%s" % (self.smartrfpath,chip,doc);
+ print "Opening %s" % fn;
+ return xml.dom.minidom.parse(fn)
+ def CMDrs(self,args=[]):
+ """Chip command to grab the radio state."""
+ self.SRF_radiostate();
+ def SRF_bitfieldstr(self,bf):
+ name="unused";
+ start=0;
+ stop=0;
+ access="";
+ reset="0x00";
+ description="";
+ for e in bf.childNodes:
+ if e.localName=="Name" and e.childNodes: name= e.childNodes[0].nodeValue;
+ elif e.localName=="Start": start=e.childNodes[0].nodeValue;
+ elif e.localName=="Stop": stop=e.childNodes[0].nodeValue;
+ return " [%s:%s] %30s " % (start,stop,name);
+ def SRF_radiostate(self):
+ ident=self.CCident();
+ chip=self.CCversions.get(ident&0xFF00);
+ dom=self.SRF_chipdom(chip,"register_definition.xml");
+ for e in dom.getElementsByTagName("registerdefinition"):
+ for f in e.childNodes:
+ if f.localName=="DeviceName":
+ print "// %s RadioState" % (f.childNodes[0].nodeValue);
+ elif f.localName=="Register":
+ name="unknownreg";
+ address="0xdead";
+ description="";
+ bitfields="";
+ for g in f.childNodes:
+ if g.localName=="Name":
+ name=g.childNodes[0].nodeValue;
+ elif g.localName=="Address":
+ address=g.childNodes[0].nodeValue;
+ elif g.localName=="Description":
+ if g.childNodes:
+ description=g.childNodes[0].nodeValue;
+ elif g.localName=="Bitfield":
+ bitfields+="%17s/* %-50s */\n" % ("",self.SRF_bitfieldstr(g));
+ #print "SFRX(%10s, %s); /* %50s */" % (name,address, description);
+ print "%-10s=0x%02x; /* %-50s */" % (
+ name,self.CCpeekdatabyte(eval(address)), description);
+ if bitfields!="": print bitfields.rstrip();
+ def CChaltcpu(self):
+ """Halt the CPU."""
+ self.writecmd(self.APP,0x86,0,self.data);
+ def CCreleasecpu(self):
+ """Resume the CPU."""
+ self.writecmd(self.APP,0x87,0,self.data);
+ def test(self):
+ self.CCreleasecpu();
+ self.CChaltcpu();
+ #print "Status: %s" % self.CCstatusstr();
+
+ #Grab ident three times, should be equal.
+ ident1=self.CCident();
+ ident2=self.CCident();
+ ident3=self.CCident();
+ if(ident1!=ident2 or ident2!=ident3):
+ print "Error, repeated ident attempts unequal."
+ print "%04x, %04x, %04x" % (ident1, ident2, ident3);
+
+ #Single step, printing PC.
+ print "Tracing execution at startup."
+ for i in range(1,15):
+ pc=self.CCgetPC();
+ byte=self.CCpeekcodebyte(i);
+ #print "PC=%04x, %02x" % (pc, byte);
+ self.CCstep_instr();
+
+ print "Verifying that debugging a NOP doesn't affect the PC."
+ for i in range(1,15):
+ pc=self.CCgetPC();
+ self.CCdebuginstr([0x00]);
+ if(pc!=self.CCgetPC()):
+ print "ERROR: PC changed during CCdebuginstr([NOP])!";
+
+ print "Checking pokes to XRAM."
+ for i in range(0xf000,0xf020):
+ self.CCpokedatabyte(i,0xde);
+ if(self.CCpeekdatabyte(i)!=0xde):
+ print "Error in XDATA at 0x%04x" % i;
+
+ #print "Status: %s." % self.CCstatusstr();
+ #Exit debugger
+ self.stop();
+ print "Done.";
+
+ def setup(self):
+ """Move the FET into the CC2430/CC2530 application."""
+ #print "Initializing Chipcon.";
+ self.writecmd(self.APP,0x10,0,self.data);
+ def CCrd_config(self):
+ """Read the config register of a Chipcon."""
+ self.writecmd(self.APP,0x82,0,self.data);
+ return ord(self.data[0]);
+ def CCwr_config(self,config):
+ """Write the config register of a Chipcon."""
+ self.writecmd(self.APP,0x81,1,[config&0xFF]);
+ def CClockchip(self):
+ """Set the flash lock bit in info mem."""
+ self.writecmd(self.APP, 0x9A, 0, None);
+ def lock(self):
+ """Set the flash lock bit in info mem."""
+ self.CClockchip();
+
+
+ CCversions={0x0100:"cc1110",
+ 0x8500:"cc2430",
+ 0x8900:"cc2431",
+ 0x8100:"cc2510",
+ 0x9100:"cc2511",
+ 0xA500:"cc2530", #page 52 of SWRU191
+ 0xB500:"cc2531",
+ 0xFF00:"CCmissing"};
+ CCpagesizes={0x01: 1024, #"CC1110",
+ 0x85: 2048, #"CC2430",
+ 0x89: 2048, #"CC2431",
+ 0x81: 1024, #"CC2510",
+ 0x91: 1024, #"CC2511",
+ 0xA5: 2048, #"CC2530", #page 52 of SWRU191
+ 0xB5: 2048, #"CC2531",
+ 0xFF: 0 } #"CCmissing"};
+ def infostring(self):
+ return self.CCidentstr();
+ def CCidentstr(self):
+ ident=self.CCident();
+ chip=self.CCversions.get(ident&0xFF00);
+ return "%s/r%02x" % (chip, ident&0xFF);
+ def CCident(self):
+ """Get a chipcon's ID."""
+ self.writecmd(self.APP,0x8B,0,None);
+ chip=ord(self.data[0]);
+ rev=ord(self.data[1]);
+ return (chip<<8)+rev;
+ def CCpagesize(self):
+ """Get a chipcon's ID."""
+ self.writecmd(self.APP,0x8B,0,None);
+ chip=ord(self.data[0]);
+ size=self.CCpagesizes.get(chip);
+ if(size<10):
+ print "ERROR: Pagesize undefined.";
+ print "chip=%02x" %chip;
+ sys.exit(1);
+ #return 2048;
+ return size;
+ def CCgetPC(self):
+ """Get a chipcon's PC."""
+ self.writecmd(self.APP,0x83,0,None);
+ hi=ord(self.data[0]);
+ lo=ord(self.data[1]);
+ return (hi<<8)+lo;
+ def CCcmd(self,phrase):
+ self.writecmd(self.APP,0x00,len(phrase),phrase);
+ val=ord(self.data[0]);
+ print "Got %02x" % val;
+ return val;
+ def CCdebuginstr(self,instr):
+ self.writecmd(self.APP,0x88,len(instr),instr);
+ return ord(self.data[0]);
+ def peek8(self,address, memory="code"):
+ if(memory=="code" or memory=="flash" or memory=="vn"):
+ return self.CCpeekcodebyte(address);
+ elif(memory=="data" or memory=="xdata" or memory=="ram"):
+ return self.CCpeekdatabyte(address);
+ elif(memory=="idata" or memory=="iram"):
+ return self.CCpeekirambyte(address);
+ print "%s is an unknown memory." % memory;
+ return 0xdead;
+ def CCpeekcodebyte(self,adr):
+ """Read the contents of code memory at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8];
+ self.writecmd(self.APP,0x90,2,self.data);
+ return ord(self.data[0]);
+ def CCpeekdatabyte(self,adr):
+ """Read the contents of data memory at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8];
+ self.writecmd(self.APP,0x91, 2, self.data);
+ return ord(self.data[0]);
+ def CCpeekirambyte(self,adr):
+ """Read the contents of IRAM at an address."""
+ self.data=[adr&0xff];
+ self.writecmd(self.APP,0x02, 1, self.data);
+ return ord(self.data[0]);
+ def CCpeekiramword(self,adr):
+ """Read the little-endian contents of IRAM at an address."""
+ return self.CCpeekirambyte(adr)+(
+ self.CCpeekirambyte(adr+1)<<8);
+ def CCpokeiramword(self,adr,val):
+ self.CCpokeirambyte(adr,val&0xff);
+ self.CCpokeirambyte(adr+1,(val>>8)&0xff);
+ def CCpokeirambyte(self,adr,val):
+ """Write the contents of IRAM at an address."""
+ self.data=[adr&0xff, val&0xff];
+ self.writecmd(self.APP,0x02, 2, self.data);
+ return ord(self.data[0]);
+
+ def CCpokedatabyte(self,adr,val):
+ """Write a byte to data memory."""
+ self.data=[adr&0xff, (adr&0xff00)>>8, val];
+ self.writecmd(self.APP, 0x92, 3, self.data);
+ return ord(self.data[0]);
+ def CCchiperase(self):
+ """Erase all of the target's memory."""
+ self.writecmd(self.APP,0x80,0,None);
+ def erase(self):
+ """Erase all of the target's memory."""
+ self.CCchiperase();
+
+ def CCstatus(self):
+ """Check the status."""
+ self.writecmd(self.APP,0x84,0,None);
+ return ord(self.data[0])
+ #Same as CC2530
+ CCstatusbits={0x80 : "erase_busy",
+ 0x40 : "pcon_idle",
+ 0x20 : "cpu_halted",
+ 0x10 : "pm0",
+ 0x08 : "halt_status",
+ 0x04 : "locked",
+ 0x02 : "oscstable",
+ 0x01 : "overflow"
+ };
+ CCconfigbits={0x20 : "soft_power_mode", #new for CC2530
+ 0x08 : "timers_off",
+ 0x04 : "dma_pause",
+ 0x02 : "timer_suspend",
+ 0x01 : "sel_flash_info_page" #stricken from CC2530
+ };
+
+ def status(self):
+ """Check the status as a string."""
+ status=self.CCstatus();
+ str="";
+ i=1;
+ while i<0x100:
+ if(status&i):
+ str="%s %s" %(self.CCstatusbits[i],str);
+ i*=2;
+ return str;
+ def start(self):
+ """Start debugging."""
+ self.setup();
+ self.writecmd(self.APP,0x20,0,self.data);
+ ident=self.CCidentstr();
+ #print "Target identifies as %s." % ident;
+ #print "Status: %s." % self.status();
+ self.CCreleasecpu();
+ self.CChaltcpu();
+ #print "Status: %s." % self.status();
+
+ def stop(self):
+ """Stop debugging."""
+ self.writecmd(self.APP,0x21,0,self.data);
+ def CCstep_instr(self):
+ """Step one instruction."""
+ self.writecmd(self.APP,0x89,0,self.data);
+ def CCeraseflashbuffer(self):
+ """Erase the 2kB flash buffer"""
+ self.writecmd(self.APP,0x99);
+ def CCflashpage(self,adr):
+ """Flash 2kB a page of flash from 0xF000 in XDATA"""
+ data=[adr&0xFF,
+ (adr>>8)&0xFF,
+ (adr>>16)&0xFF,
+ (adr>>24)&0xFF];
+ print "Flashing buffer to 0x%06x" % adr;
+ self.writecmd(self.APP,0x95,4,data);
+
+ def flash(self,file):
+ """Flash an intel hex file to code memory."""
+ print "Flashing %s" % file;
+
+ h = IntelHex(file);
+ page = 0x0000;
+ pagelen = self.CCpagesize(); #Varies by chip.
+
+ #print "page=%04x, pagelen=%04x" % (page,pagelen);
+
+ bcount = 0;
+
+ #Wipe the RAM buffer for the next flash page.
+ self.CCeraseflashbuffer();
+ for i in h._buf.keys():
+ while(i>=page+pagelen):
+ if bcount>0:
+ self.CCflashpage(page);
+ #client.CCeraseflashbuffer();
+ bcount=0;
+ print "Flashed page at %06x" % page
+ page+=pagelen;
+
+ #Place byte into buffer.
+ self.CCpokedatabyte(0xF000+i-page,
+ h[i]);
+ bcount+=1;
+ if(i%0x100==0):
+ print "Buffering %04x toward %06x" % (i,page);
+ #last page
+ self.CCflashpage(page);
+ print "Flashed final page at %06x" % page;
+
--- /dev/null
+#!/usr/bin/env python
+# GoodFET Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, os;
+import binascii;
+
+from GoodFET import GoodFET;
+from intelhex import IntelHex;
+
+class GoodFETConsole():
+ """An interactive goodfet driver."""
+
+ def __init__(self, client):
+ self.client=client;
+ client.serInit();
+ client.setup();
+ client.start();
+ def prompt(self):
+ sys.stdout.write("gf% ");
+ sys.stdout.flush();
+ def run(self):
+ self.prompt();
+ #for cmd in sys.stdin:
+ while 1:
+ cmd=sys.stdin.readline();
+ if not cmd: break;
+ if(cmd.strip()!=""):
+ self.handle(cmd);
+ self.prompt();
+ def handle(self, str):
+ """Handle a command string. First word is command."""
+ #Lines beginning with # are comments.
+ if(str[0]=="#"): return;
+ #Lines beginning with ! are Python.
+ if(str[0]=="!"):
+ try:
+ exec(str.lstrip('!'));
+ except:
+ print sys.exc_info()[0];
+ return;
+ #Backtick (`) indicates shell commands.
+ if(str[0]=='`'):
+ os.system(str.lstrip('`'));
+ return;
+ #By this point, we're looking at a GoodFET command.
+ args=str.split();
+ if len(args)==0:
+ return;
+ try:
+ eval("self.CMD%s(args)" % args[0])
+ except:
+ print sys.exc_info()[0];
+ #print "Unknown command '%s'." % args[0];
+ def CMDinfo(self,args):
+ print self.client.infostring()
+ def CMDlock(self,args):
+ print "Locking.";
+ self.client.lock();
+ def CMDerase(self,args):
+ print "Erasing.";
+ self.client.erase();
+ def CMDtest(self,args):
+ self.client.test();
+ return;
+ def CMDstatus(self,args):
+ print self.client.status();
+ return;
+ def CMDpeek(self,args):
+ adr=eval(args[1]);
+ memory="vn";
+ if(len(args)>2):
+ memory=args[2];
+ print "0x%08x:= 0x%04x" % (adr, self.client.peek16(adr,memory));
+ def CMDflash(self,args):
+ file=args[1];
+ self.client.flash(self.expandfilename(file));
+ def CMDchip(self,args):
+ cmd="self.client.CMD%s()" % args[1];
+ print cmd;
+ try:
+ eval(cmd);
+ except:
+ print sys.exc_info()[0];
+ print "Chip-specific command failed.";
+ def expandfilename(self,filename):
+ if(filename[0]=='~'):
+ return "%s%s" % (os.environ.get("HOME"),filename.lstrip('~'));
+ return filename;
+
+
--- /dev/null
+#!/usr/bin/env python
+# GoodFET Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# Presently being rewritten.
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+from GoodFET import GoodFET;
+
+class GoodFETMSP430(GoodFET):
+ MSP430APP=0x11; #Changed by inheritors.
+ CoreID=0;
+ DeviceID=0;
+ JTAGID=0;
+ MSP430ident=0;
+ def MSP430setup(self):
+ """Move the FET into the MSP430 JTAG application."""
+ self.writecmd(self.MSP430APP,0x10,0,None);
+
+ def MSP430stop(self):
+ """Stop debugging."""
+ self.writecmd(self.MSP430APP,0x21,0,self.data);
+
+ def MSP430coreid(self):
+ """Get the Core ID."""
+ self.writecmd(self.MSP430APP,0xF0);
+ CoreID=ord(self.data[0])+(ord(self.data[1])<<8);
+ return CoreID;
+ def MSP430deviceid(self):
+ """Get the Core ID."""
+ self.writecmd(self.MSP430APP,0xF1);
+ DeviceID=(
+ ord(self.data[0])+(ord(self.data[1])<<8)+
+ (ord(self.data[2])<<16)+(ord(self.data[3])<<24));
+ return DeviceID;
+ def MSP430peek(self,adr):
+ """Read a word at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ ];
+ self.writecmd(self.MSP430APP,0x02,4,self.data);
+
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+ def MSP430peekblock(self,adr):
+ """Grab a few block from an SPI Flash ROM. Block size is unknown"""
+ data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ 0x00,0x04];
+ self.writecmd(self.MSP430APP,0x02,6,data);
+ return self.data;
+
+ def MSP430poke(self,adr,val):
+ """Write the contents of memory at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ val&0xff, (val&0xff00)>>8];
+ self.writecmd(self.MSP430APP,0x03,6,self.data);
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+ def MSP430pokeflash(self,adr,val):
+ """Write the contents of flash memory at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ val&0xff, (val&0xff00)>>8];
+ self.writecmd(self.MSP430APP,0xE1,6,self.data);
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+ def MSP430pokeflashblock(self,adr,data):
+ """Write many words to flash memory at an address."""
+ self.data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24]+data;
+ #print "Writing %i bytes to %x" % (len(data),adr);
+ #print "%2x %2x %2x %2x ..." % (data[0], data[1], data[2], data[3]);
+ self.writecmd(self.MSP430APP,0xE1,len(self.data),self.data);
+ return ord(self.data[0])+(ord(self.data[1])<<8);
+ def MSP430start(self):
+ """Start debugging."""
+ self.writecmd(self.MSP430APP,0x20,0,self.data);
+ self.JTAGID=ord(self.data[0]);
+ #print "Identified as %02x." % self.JTAGID;
+ if(not (self.JTAGID==0x89 or self.JTAGID==0x91)):
+ print "Error, misidentified as %02x." % self.JTAGID;
+
+ def MSP430haltcpu(self):
+ """Halt the CPU."""
+ self.writecmd(self.MSP430APP,0xA0,0,self.data);
+ def MSP430releasecpu(self):
+ """Resume the CPU."""
+ self.writecmd(self.MSP430APP,0xA1,0,self.data);
+ def MSP430shiftir8(self,ins):
+ """Shift the 8-bit Instruction Register."""
+ data=[ins];
+ self.writecmd(self.MSP430APP,0x80,1,data);
+ return ord(self.data[0]);
+ def MSP430shiftdr16(self,dat):
+ """Shift the 16-bit Data Register."""
+ data=[dat&0xFF,(dat&0xFF00)>>8];
+ self.writecmd(self.MSP430APP,0x81,2,data);
+ return ord(self.data[0])#+(ord(self.data[1])<<8);
+ def MSP430setinstrfetch(self):
+ """Set the instruction fetch mode."""
+ self.writecmd(self.MSP430APP,0xC1,0,self.data);
+ return self.data[0];
+ def MSP430ident(self):
+ """Grab self-identification word from 0x0FF0 as big endian."""
+ ident=0x00;
+ if(self.JTAGID==0x89):
+ i=self.MSP430peek(0x0ff0);
+ ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
+
+ if(self.JTAGID==0x91):
+ i=self.MSP430peek(0x1A04);
+ ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
+ #ident=0x0091;
+
+ return ident;
+ def MSP430identstr(self):
+ """Grab model string."""
+ return self.MSP430devices.get(self.MSP430ident());
+ MSP430devices={
+ #MSP430F2xx
+ 0xf227: "MSP430F22xx",
+ 0xf213: "MSP430F21x1",
+ 0xf249: "MSP430F24x",
+ 0xf26f: "MSP430F261x",
+ 0xf237: "MSP430F23x0",
+
+
+ #MSP430F1xx
+ 0xf16c: "MSP430F161x",
+ 0xf149: "MSP430F13x", #or f14x(1)
+ 0xf112: "MSP430F11x", #or f11x1
+ 0xf143: "MSP430F14x",
+ 0xf112: "MSP430F11x", #or F11x1A
+ 0xf123: "MSP430F1xx", #or F123x
+ 0x1132: "MSP430F1122", #or F1132
+ 0x1232: "MSP430F1222", #or F1232
+ 0xf169: "MSP430F16x",
+
+ #MSP430F4xx
+ 0xF449: "MSP430F43x", #or F44x
+ 0xF427: "MSP430FE42x", #or FW42x, F415, F417
+ 0xF439: "MSP430FG43x",
+ 0xf46f: "MSP430FG46xx", #or F471xx
+
+ }
+ def MSP430test(self):
+ """Test MSP430 JTAG. Requires that a chip be attached."""
+
+ if self.MSP430ident()==0xffff:
+ print "ERROR Is anything connected?";
+ print "Testing %s." % self.MSP430identstr();
+ print "Testing RAM from 200 to 210.";
+ for a in range(0x200,0x210):
+ self.MSP430poke(a,0);
+ if(self.MSP430peek(a)!=0):
+ print "Fault at %06x" % a;
+ self.MSP430poke(a,0xffff);
+ if(self.MSP430peek(a)!=0xffff):
+ print "Fault at %06x" % a;
+
+ print "Testing identity consistency."
+ ident=self.MSP430ident();
+ for a in range(1,20):
+ ident2=self.MSP430ident();
+ if ident!=ident2:
+ print "Identity %04x!=%04x" % (ident,ident2);
+
+ print "Testing flash erase."
+ self.MSP430masserase();
+ for a in range(0xffe0, 0xffff):
+ if self.MSP430peek(a)!=0xffff:
+ print "%04x unerased, equals %04x" % (
+ a, self.MSP430peek(a));
+
+ print "Testing flash write."
+ for a in range(0xffe0, 0xffff):
+ self.MSP430pokeflash(a,0xbeef);
+ if self.MSP430peek(a)!=0xbeef:
+ print "%04x unset, equals %04x" % (
+ a, self.MSP430peek(a));
+
+ print "Tests complete, erasing."
+ self.MSP430masserase();
+
+ def MSP430masserase(self):
+ """Erase MSP430 flash memory."""
+ self.writecmd(self.MSP430APP,0xE3,0,None);
+ def MSP430setPC(self, pc):
+ """Set the program counter."""
+ self.writecmd(self.MSP430APP,0xC2,2,[pc&0xFF,(pc>>8)&0xFF]);
+ def MSP430run(self):
+ """Reset the MSP430 to run on its own."""
+ self.writecmd(self.MSP430APP,0x21,0,None);
+ def MSP430dumpbsl(self):
+ self.MSP430dumpmem(0xC00,0xfff);
+ def MSP430dumpallmem(self):
+ self.MSP430dumpmem(0x200,0xffff);
+ def MSP430dumpmem(self,begin,end):
+ i=begin;
+ while i<end:
+ print "%04x %04x" % (i, self.MSP430peek(i));
+ i+=2;
--- /dev/null
+#!/usr/bin/env python
+# GoodFET SPI and SPIFlash Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+from GoodFET import GoodFET;
+
+class GoodFETSPI(GoodFET):
+ def SPIsetup(self):
+ """Move the FET into the SPI application."""
+ self.writecmd(0x01,0x10,0,self.data); #SPI/SETUP
+
+ def SPItrans8(self,byte):
+ """Read and write 8 bits by SPI."""
+ data=self.SPItrans([byte]);
+ return ord(data[0]);
+
+ def SPItrans(self,data):
+ """Exchange data by SPI."""
+ self.data=data;
+ self.writecmd(0x01,0x00,len(data),data);
+ return self.data;
+
+class GoodFETSPIFlash(GoodFETSPI):
+ JEDECmanufacturers={0xFF: "MISSING",
+ 0xEF: "Winbond",
+ 0xC2: "MXIC",
+ 0x20: "Numonyx/ST",
+ 0x1F: "Atmel",
+ 0x01: "AMD/Spansion"
+ };
+
+ JEDECdevices={0xFFFFFF: "MISSING",
+ 0xEF3015: "W25X16L",
+ 0xEF3014: "W25X80L",
+ 0xEF3013: "W25X40L",
+ 0xEF3012: "W25X20L",
+ 0xEF3011: "W25X10L",
+ 0xC22017: "MX25L6405D",
+ 0xC22016: "MX25L3205D",
+ 0xC22015: "MX25L1605D",
+ 0xC22014: "MX25L8005",
+ 0xC22013: "MX25L4005",
+ 0x204011: "M45PE10"
+ };
+
+ JEDECsizes={0x17: 0x800000,
+ 0x16: 0x400000,
+ 0x15: 0x200000,
+ 0x14: 0x100000,
+ 0x13: 0x080000,
+ 0x12: 0x040000,
+ 0x11: 0x020000
+ };
+
+ JEDECsize=0;
+
+ def SPIjedec(self):
+ """Grab an SPI Flash ROM's JEDEC bytes."""
+ data=[0x9f, 0, 0, 0];
+ data=self.SPItrans(data);
+
+ self.JEDECmanufacturer=ord(data[1]);
+ self.JEDECtype=ord(data[2]);
+ self.JEDECcapacity=ord(data[3]);
+ self.JEDECsize=self.JEDECsizes.get(self.JEDECcapacity);
+ if self.JEDECsize==None:
+ self.JEDECsize=0;
+ self.JEDECdevice=(ord(data[1])<<16)+(ord(data[2])<<8)+ord(data[3]);
+ return data;
+ def SPIpeek(self,adr):
+ """Grab a byte from an SPI Flash ROM."""
+ data=[0x03,
+ (adr&0xFF0000)>>16,
+ (adr&0xFF00)>>8,
+ adr&0xFF,
+ 0];
+ self.SPItrans(data);
+ return ord(self.data[4]);
+ def SPIpeekblock(self,adr):
+ """Grab a few block from an SPI Flash ROM. Block size is unknown"""
+ data=[(adr&0xFF0000)>>16,
+ (adr&0xFF00)>>8,
+ adr&0xFF];
+
+ self.writecmd(0x01,0x02,3,data);
+ return self.data;
+
+ def SPIpokebyte(self,adr,val):
+ self.SPIpokebytes(adr,[val]);
+ def SPIpokebytes(self,adr,data):
+ #Used to be 24 bits, BE, not 32 bits, LE.
+ adranddata=[adr&0xFF,
+ (adr&0xFF00)>>8,
+ (adr&0xFF0000)>>16,
+ 0, #MSB
+ ]+data;
+ #print "%06x: poking %i bytes" % (adr,len(data));
+ self.writecmd(0x01,0x03,
+ len(adranddata),adranddata);
+
+ def SPIchiperase(self):
+ """Mass erase an SPI Flash ROM."""
+ self.writecmd(0x01,0x81);
+ def SPIwriteenable(self):
+ """SPI Flash Write Enable"""
+ data=[0x06];
+ self.SPItrans(data);
+
+ def SPIjedecmanstr(self):
+ """Grab the JEDEC manufacturer string. Call after SPIjedec()."""
+ man=self.JEDECmanufacturers.get(self.JEDECmanufacturer)
+ if man==0:
+ man="UNKNOWN";
+ return man;
+
+ def SPIjedecstr(self):
+ """Grab the JEDEC manufacturer string. Call after SPIjedec()."""
+ man=self.JEDECmanufacturers.get(self.JEDECmanufacturer);
+ if man==0:
+ man="UNKNOWN";
+ device=self.JEDECdevices.get(self.JEDECdevice);
+ if device==0:
+ device="???"
+ return "%s %s" % (man,device);
+
--- /dev/null
+#!/usr/bin/env python
+# GoodFET SPI and SPIFlash Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+from GoodFET import GoodFET;
+
+class GoodFETSmartCard(GoodFET):
+ SMARTCARDAPP=0x73;
+ APP=SMARTCARDAPP;
+
+ def setup(self):
+ """Move the FET into the SmartCard application."""
+ self.writecmd(self.APP,0x10,0,self.data);
+ def start(self):
+ """Start the connection, reat ATR."""
+ self.writecmd(self.APP,0x20,0,None);
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET SPI and SPIFlash Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys, time, string, cStringIO, struct, glob, serial, os;
-
-from GoodFET import GoodFET;
-
-class GoodFETAVR(GoodFET):
- AVRAPP=0x32;
- APP=AVRAPP;
- AVRVendors={0x1E: "Atmel",
- 0x00: "Locked",
- };
-
- #List from avr910.asm and other sources.
- #More devices at http://avr.fenceline.de/device_data.html
- AVRDevices={
- 0x9003: "tiny10",
- 0x9004: "tiny11",
- 0x9005: "tiny12",
- 0x9006: "tiny15",
- 0x9007: "tiny13",
- 0x9108: "tiny25",
- 0x930B: "tiny85",
- 0x9206: "tiny45",
-
- 0x9001: "S1200",
-
- 0x9101: "S1213",
- 0x9102: "S2323",
- 0x9105: "S2333",
- 0x9103: "S2343",
-
- 0x9201: "S4414",
- 0x9203: "S4433",
- 0x9202: "S4434",
-
- 0x9301: "S8515",
- 0x9303: "S8535",
-
- 0x9305: "mega83",
- 0x930a: "mega88",
- 0x9701: "mega103",
- 0x9401: "mega161",
- 0x9402: "mega163",
- 0x9406: "mega168",
-
- 0x950f: "mega328",
- 0x950d: "mega325",
- 0x9508: "mega32"
- };
-
- def setup(self):
- """Move the FET into the AVR application."""
- self.writecmd(self.AVRAPP,0x10,0,self.data); #SPI/SETUP
-
- def trans(self,data):
- """Exchange data by AVR.
- Input should probably be 4 bytes."""
- self.data=data;
- self.writecmd(self.AVRAPP,0x00,len(data),data);
- return self.data;
-
- def start(self):
- """Start the connection."""
- self.writecmd(self.AVRAPP,0x20,0,None);
- def forcestart(self):
- """Forcibly start a connection."""
-
- for i in range(0x880,0xfff):
- #self.glitchVoltages(0x880, i);
- self.start();
- bits=self.lockbits();
- print "At %04x, Lockbits: %02x" % (i,bits);
- if(bits==0xFF): return;
- def erase(self):
- """Erase the target chip."""
- self.writecmd(self.AVRAPP,0xF0,0,None);
- def lockbits(self):
- """Read the target's lockbits."""
- self.writecmd(self.AVRAPP,0x82,0,None);
- return ord(self.data[0]);
- def setlockbits(self,bits=0x00):
- """Read the target's lockbits."""
- self.writecmd(self.AVRAPP,0x92,1,[bits]);
- return self.lockbits();
-
- def eeprompeek(self, adr):
- """Read a byte of the target's EEPROM."""
- self.writecmd(self.AVRAPP,0x81 ,2,
- [ (adr&0xFF), (adr>>8)]
- );#little-endian address
- return ord(self.data[0]);
- def flashpeek(self, adr):
- """Read a byte of the target's EEPROM."""
- self.writecmd(self.AVRAPP,0x02 ,2,
- [ (adr&0xFF), (adr>>8)]
- );#little-endian address
- return ord(self.data[0]);
- def flashpeekblock(self, adr):
- """Read a byte of the target's EEPROM."""
- self.writecmd(self.AVRAPP,0x02 ,4,
- [ (adr&0xFF), (adr>>8) &0xFF, 0x80, 0x00]
- );
- return self.data;
-
- def eeprompoke(self, adr, val):
- """Write a byte of the target's EEPROM."""
- self.writecmd(self.AVRAPP,0x91 ,3,
- [ (adr&0xFF), (adr>>8), val]
- );#little-endian address
- return ord(self.data[0]);
-
- def identstr(self):
- """Return an identifying string."""
- self.writecmd(self.AVRAPP,0x83,0, None);
- vendor=self.AVRVendors.get(ord(self.data[0]));
- deviceid=(ord(self.data[1])<<8)+ord(self.data[2]);
- device=self.AVRDevices.get(deviceid);
-
- #Return hex if device is unknown.
- #They are similar enough that it needn't be known.
- if device==None:
- device=("0x%04x" % deviceid);
-
- return "%s %s" % (vendor,device);
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys;
-import binascii;
-
-from GoodFET import GoodFET;
-from intelhex import IntelHex;
-
-import xml.dom.minidom;
-
-class GoodFETCC(GoodFET):
- """A GoodFET variant for use with Chipcon 8051 Zigbee SoC."""
- APP=0x30;
- smartrfpath="/opt/smartrf7";
- def SRF_chipdom(self,chip="cc1110", doc="register_definition.xml"):
- fn="%s/config/xml/%s/%s" % (self.smartrfpath,chip,doc);
- print "Opening %s" % fn;
- return xml.dom.minidom.parse(fn)
- def CMDrs(self,args=[]):
- """Chip command to grab the radio state."""
- self.SRF_radiostate();
- def SRF_bitfieldstr(self,bf):
- name="unused";
- start=0;
- stop=0;
- access="";
- reset="0x00";
- description="";
- for e in bf.childNodes:
- if e.localName=="Name" and e.childNodes: name= e.childNodes[0].nodeValue;
- elif e.localName=="Start": start=e.childNodes[0].nodeValue;
- elif e.localName=="Stop": stop=e.childNodes[0].nodeValue;
- return " [%s:%s] %30s " % (start,stop,name);
- def SRF_radiostate(self):
- ident=self.CCident();
- chip=self.CCversions.get(ident&0xFF00);
- dom=self.SRF_chipdom(chip,"register_definition.xml");
- for e in dom.getElementsByTagName("registerdefinition"):
- for f in e.childNodes:
- if f.localName=="DeviceName":
- print "// %s RadioState" % (f.childNodes[0].nodeValue);
- elif f.localName=="Register":
- name="unknownreg";
- address="0xdead";
- description="";
- bitfields="";
- for g in f.childNodes:
- if g.localName=="Name":
- name=g.childNodes[0].nodeValue;
- elif g.localName=="Address":
- address=g.childNodes[0].nodeValue;
- elif g.localName=="Description":
- if g.childNodes:
- description=g.childNodes[0].nodeValue;
- elif g.localName=="Bitfield":
- bitfields+="%17s/* %-50s */\n" % ("",self.SRF_bitfieldstr(g));
- #print "SFRX(%10s, %s); /* %50s */" % (name,address, description);
- print "%-10s=0x%02x; /* %-50s */" % (
- name,self.CCpeekdatabyte(eval(address)), description);
- if bitfields!="": print bitfields.rstrip();
- def CChaltcpu(self):
- """Halt the CPU."""
- self.writecmd(self.APP,0x86,0,self.data);
- def CCreleasecpu(self):
- """Resume the CPU."""
- self.writecmd(self.APP,0x87,0,self.data);
- def test(self):
- self.CCreleasecpu();
- self.CChaltcpu();
- #print "Status: %s" % self.CCstatusstr();
-
- #Grab ident three times, should be equal.
- ident1=self.CCident();
- ident2=self.CCident();
- ident3=self.CCident();
- if(ident1!=ident2 or ident2!=ident3):
- print "Error, repeated ident attempts unequal."
- print "%04x, %04x, %04x" % (ident1, ident2, ident3);
-
- #Single step, printing PC.
- print "Tracing execution at startup."
- for i in range(1,15):
- pc=self.CCgetPC();
- byte=self.CCpeekcodebyte(i);
- #print "PC=%04x, %02x" % (pc, byte);
- self.CCstep_instr();
-
- print "Verifying that debugging a NOP doesn't affect the PC."
- for i in range(1,15):
- pc=self.CCgetPC();
- self.CCdebuginstr([0x00]);
- if(pc!=self.CCgetPC()):
- print "ERROR: PC changed during CCdebuginstr([NOP])!";
-
- print "Checking pokes to XRAM."
- for i in range(0xf000,0xf020):
- self.CCpokedatabyte(i,0xde);
- if(self.CCpeekdatabyte(i)!=0xde):
- print "Error in XDATA at 0x%04x" % i;
-
- #print "Status: %s." % self.CCstatusstr();
- #Exit debugger
- self.stop();
- print "Done.";
-
- def setup(self):
- """Move the FET into the CC2430/CC2530 application."""
- #print "Initializing Chipcon.";
- self.writecmd(self.APP,0x10,0,self.data);
- def CCrd_config(self):
- """Read the config register of a Chipcon."""
- self.writecmd(self.APP,0x82,0,self.data);
- return ord(self.data[0]);
- def CCwr_config(self,config):
- """Write the config register of a Chipcon."""
- self.writecmd(self.APP,0x81,1,[config&0xFF]);
- def CClockchip(self):
- """Set the flash lock bit in info mem."""
- self.writecmd(self.APP, 0x9A, 0, None);
- def lock(self):
- """Set the flash lock bit in info mem."""
- self.CClockchip();
-
-
- CCversions={0x0100:"cc1110",
- 0x8500:"cc2430",
- 0x8900:"cc2431",
- 0x8100:"cc2510",
- 0x9100:"cc2511",
- 0xA500:"cc2530", #page 52 of SWRU191
- 0xB500:"cc2531",
- 0xFF00:"CCmissing"};
- CCpagesizes={0x01: 1024, #"CC1110",
- 0x85: 2048, #"CC2430",
- 0x89: 2048, #"CC2431",
- 0x81: 1024, #"CC2510",
- 0x91: 1024, #"CC2511",
- 0xA5: 2048, #"CC2530", #page 52 of SWRU191
- 0xB5: 2048, #"CC2531",
- 0xFF: 0 } #"CCmissing"};
- def infostring(self):
- return self.CCidentstr();
- def CCidentstr(self):
- ident=self.CCident();
- chip=self.CCversions.get(ident&0xFF00);
- return "%s/r%02x" % (chip, ident&0xFF);
- def CCident(self):
- """Get a chipcon's ID."""
- self.writecmd(self.APP,0x8B,0,None);
- chip=ord(self.data[0]);
- rev=ord(self.data[1]);
- return (chip<<8)+rev;
- def CCpagesize(self):
- """Get a chipcon's ID."""
- self.writecmd(self.APP,0x8B,0,None);
- chip=ord(self.data[0]);
- size=self.CCpagesizes.get(chip);
- if(size<10):
- print "ERROR: Pagesize undefined.";
- print "chip=%02x" %chip;
- sys.exit(1);
- #return 2048;
- return size;
- def CCgetPC(self):
- """Get a chipcon's PC."""
- self.writecmd(self.APP,0x83,0,None);
- hi=ord(self.data[0]);
- lo=ord(self.data[1]);
- return (hi<<8)+lo;
- def CCcmd(self,phrase):
- self.writecmd(self.APP,0x00,len(phrase),phrase);
- val=ord(self.data[0]);
- print "Got %02x" % val;
- return val;
- def CCdebuginstr(self,instr):
- self.writecmd(self.APP,0x88,len(instr),instr);
- return ord(self.data[0]);
- def peek8(self,address, memory="code"):
- if(memory=="code" or memory=="flash" or memory=="vn"):
- return self.CCpeekcodebyte(address);
- elif(memory=="data" or memory=="xdata" or memory=="ram"):
- return self.CCpeekdatabyte(address);
- elif(memory=="idata" or memory=="iram"):
- return self.CCpeekirambyte(address);
- print "%s is an unknown memory." % memory;
- return 0xdead;
- def CCpeekcodebyte(self,adr):
- """Read the contents of code memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8];
- self.writecmd(self.APP,0x90,2,self.data);
- return ord(self.data[0]);
- def CCpeekdatabyte(self,adr):
- """Read the contents of data memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8];
- self.writecmd(self.APP,0x91, 2, self.data);
- return ord(self.data[0]);
- def CCpeekirambyte(self,adr):
- """Read the contents of IRAM at an address."""
- self.data=[adr&0xff];
- self.writecmd(self.APP,0x02, 1, self.data);
- return ord(self.data[0]);
- def CCpeekiramword(self,adr):
- """Read the little-endian contents of IRAM at an address."""
- return self.CCpeekirambyte(adr)+(
- self.CCpeekirambyte(adr+1)<<8);
- def CCpokeiramword(self,adr,val):
- self.CCpokeirambyte(adr,val&0xff);
- self.CCpokeirambyte(adr+1,(val>>8)&0xff);
- def CCpokeirambyte(self,adr,val):
- """Write the contents of IRAM at an address."""
- self.data=[adr&0xff, val&0xff];
- self.writecmd(self.APP,0x02, 2, self.data);
- return ord(self.data[0]);
-
- def CCpokedatabyte(self,adr,val):
- """Write a byte to data memory."""
- self.data=[adr&0xff, (adr&0xff00)>>8, val];
- self.writecmd(self.APP, 0x92, 3, self.data);
- return ord(self.data[0]);
- def CCchiperase(self):
- """Erase all of the target's memory."""
- self.writecmd(self.APP,0x80,0,None);
- def erase(self):
- """Erase all of the target's memory."""
- self.CCchiperase();
-
- def CCstatus(self):
- """Check the status."""
- self.writecmd(self.APP,0x84,0,None);
- return ord(self.data[0])
- #Same as CC2530
- CCstatusbits={0x80 : "erase_busy",
- 0x40 : "pcon_idle",
- 0x20 : "cpu_halted",
- 0x10 : "pm0",
- 0x08 : "halt_status",
- 0x04 : "locked",
- 0x02 : "oscstable",
- 0x01 : "overflow"
- };
- CCconfigbits={0x20 : "soft_power_mode", #new for CC2530
- 0x08 : "timers_off",
- 0x04 : "dma_pause",
- 0x02 : "timer_suspend",
- 0x01 : "sel_flash_info_page" #stricken from CC2530
- };
-
- def status(self):
- """Check the status as a string."""
- status=self.CCstatus();
- str="";
- i=1;
- while i<0x100:
- if(status&i):
- str="%s %s" %(self.CCstatusbits[i],str);
- i*=2;
- return str;
- def start(self):
- """Start debugging."""
- self.setup();
- self.writecmd(self.APP,0x20,0,self.data);
- ident=self.CCidentstr();
- #print "Target identifies as %s." % ident;
- #print "Status: %s." % self.status();
- self.CCreleasecpu();
- self.CChaltcpu();
- #print "Status: %s." % self.status();
-
- def stop(self):
- """Stop debugging."""
- self.writecmd(self.APP,0x21,0,self.data);
- def CCstep_instr(self):
- """Step one instruction."""
- self.writecmd(self.APP,0x89,0,self.data);
- def CCeraseflashbuffer(self):
- """Erase the 2kB flash buffer"""
- self.writecmd(self.APP,0x99);
- def CCflashpage(self,adr):
- """Flash 2kB a page of flash from 0xF000 in XDATA"""
- data=[adr&0xFF,
- (adr>>8)&0xFF,
- (adr>>16)&0xFF,
- (adr>>24)&0xFF];
- print "Flashing buffer to 0x%06x" % adr;
- self.writecmd(self.APP,0x95,4,data);
-
- def flash(self,file):
- """Flash an intel hex file to code memory."""
- print "Flashing %s" % file;
-
- h = IntelHex(file);
- page = 0x0000;
- pagelen = self.CCpagesize(); #Varies by chip.
-
- #print "page=%04x, pagelen=%04x" % (page,pagelen);
-
- bcount = 0;
-
- #Wipe the RAM buffer for the next flash page.
- self.CCeraseflashbuffer();
- for i in h._buf.keys():
- while(i>=page+pagelen):
- if bcount>0:
- self.CCflashpage(page);
- #client.CCeraseflashbuffer();
- bcount=0;
- print "Flashed page at %06x" % page
- page+=pagelen;
-
- #Place byte into buffer.
- self.CCpokedatabyte(0xF000+i-page,
- h[i]);
- bcount+=1;
- if(i%0x100==0):
- print "Buffering %04x toward %06x" % (i,page);
- #last page
- self.CCflashpage(page);
- print "Flashed final page at %06x" % page;
-
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys, os;
-import binascii;
-
-from GoodFET import GoodFET;
-from intelhex import IntelHex;
-
-class GoodFETConsole():
- """An interactive goodfet driver."""
-
- def __init__(self, client):
- self.client=client;
- client.serInit();
- client.setup();
- client.start();
- def prompt(self):
- sys.stdout.write("gf% ");
- sys.stdout.flush();
- def run(self):
- self.prompt();
- #for cmd in sys.stdin:
- while 1:
- cmd=sys.stdin.readline();
- if not cmd: break;
- if(cmd.strip()!=""):
- self.handle(cmd);
- self.prompt();
- def handle(self, str):
- """Handle a command string. First word is command."""
- #Lines beginning with # are comments.
- if(str[0]=="#"): return;
- #Lines beginning with ! are Python.
- if(str[0]=="!"):
- try:
- exec(str.lstrip('!'));
- except:
- print sys.exc_info()[0];
- return;
- #Backtick (`) indicates shell commands.
- if(str[0]=='`'):
- os.system(str.lstrip('`'));
- return;
- #By this point, we're looking at a GoodFET command.
- args=str.split();
- if len(args)==0:
- return;
- try:
- eval("self.CMD%s(args)" % args[0])
- except:
- print sys.exc_info()[0];
- #print "Unknown command '%s'." % args[0];
- def CMDinfo(self,args):
- print self.client.infostring()
- def CMDlock(self,args):
- print "Locking.";
- self.client.lock();
- def CMDerase(self,args):
- print "Erasing.";
- self.client.erase();
- def CMDtest(self,args):
- self.client.test();
- return;
- def CMDstatus(self,args):
- print self.client.status();
- return;
- def CMDpeek(self,args):
- adr=eval(args[1]);
- memory="vn";
- if(len(args)>2):
- memory=args[2];
- print "0x%08x:= 0x%04x" % (adr, self.client.peek16(adr,memory));
- def CMDflash(self,args):
- file=args[1];
- self.client.flash(self.expandfilename(file));
- def CMDchip(self,args):
- cmd="self.client.CMD%s()" % args[1];
- print cmd;
- try:
- eval(cmd);
- except:
- print sys.exc_info()[0];
- print "Chip-specific command failed.";
- def expandfilename(self,filename):
- if(filename[0]=='~'):
- return "%s%s" % (os.environ.get("HOME"),filename.lstrip('~'));
- return filename;
-
-
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# Presently being rewritten.
-
-import sys, time, string, cStringIO, struct, glob, serial, os;
-
-from GoodFET import GoodFET;
-
-class GoodFETMSP430(GoodFET):
- MSP430APP=0x11; #Changed by inheritors.
- CoreID=0;
- DeviceID=0;
- JTAGID=0;
- MSP430ident=0;
- def MSP430setup(self):
- """Move the FET into the MSP430 JTAG application."""
- self.writecmd(self.MSP430APP,0x10,0,None);
-
- def MSP430stop(self):
- """Stop debugging."""
- self.writecmd(self.MSP430APP,0x21,0,self.data);
-
- def MSP430coreid(self):
- """Get the Core ID."""
- self.writecmd(self.MSP430APP,0xF0);
- CoreID=ord(self.data[0])+(ord(self.data[1])<<8);
- return CoreID;
- def MSP430deviceid(self):
- """Get the Core ID."""
- self.writecmd(self.MSP430APP,0xF1);
- DeviceID=(
- ord(self.data[0])+(ord(self.data[1])<<8)+
- (ord(self.data[2])<<16)+(ord(self.data[3])<<24));
- return DeviceID;
- def MSP430peek(self,adr):
- """Read a word at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24,
- ];
- self.writecmd(self.MSP430APP,0x02,4,self.data);
-
- return ord(self.data[0])+(ord(self.data[1])<<8);
- def MSP430peekblock(self,adr):
- """Grab a few block from an SPI Flash ROM. Block size is unknown"""
- data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24,
- 0x00,0x04];
- self.writecmd(self.MSP430APP,0x02,6,data);
- return self.data;
-
- def MSP430poke(self,adr,val):
- """Write the contents of memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24,
- val&0xff, (val&0xff00)>>8];
- self.writecmd(self.MSP430APP,0x03,6,self.data);
- return ord(self.data[0])+(ord(self.data[1])<<8);
- def MSP430pokeflash(self,adr,val):
- """Write the contents of flash memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24,
- val&0xff, (val&0xff00)>>8];
- self.writecmd(self.MSP430APP,0xE1,6,self.data);
- return ord(self.data[0])+(ord(self.data[1])<<8);
- def MSP430pokeflashblock(self,adr,data):
- """Write many words to flash memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24]+data;
- #print "Writing %i bytes to %x" % (len(data),adr);
- #print "%2x %2x %2x %2x ..." % (data[0], data[1], data[2], data[3]);
- self.writecmd(self.MSP430APP,0xE1,len(self.data),self.data);
- return ord(self.data[0])+(ord(self.data[1])<<8);
- def MSP430start(self):
- """Start debugging."""
- self.writecmd(self.MSP430APP,0x20,0,self.data);
- self.JTAGID=ord(self.data[0]);
- #print "Identified as %02x." % self.JTAGID;
- if(not (self.JTAGID==0x89 or self.JTAGID==0x91)):
- print "Error, misidentified as %02x." % self.JTAGID;
-
- def MSP430haltcpu(self):
- """Halt the CPU."""
- self.writecmd(self.MSP430APP,0xA0,0,self.data);
- def MSP430releasecpu(self):
- """Resume the CPU."""
- self.writecmd(self.MSP430APP,0xA1,0,self.data);
- def MSP430shiftir8(self,ins):
- """Shift the 8-bit Instruction Register."""
- data=[ins];
- self.writecmd(self.MSP430APP,0x80,1,data);
- return ord(self.data[0]);
- def MSP430shiftdr16(self,dat):
- """Shift the 16-bit Data Register."""
- data=[dat&0xFF,(dat&0xFF00)>>8];
- self.writecmd(self.MSP430APP,0x81,2,data);
- return ord(self.data[0])#+(ord(self.data[1])<<8);
- def MSP430setinstrfetch(self):
- """Set the instruction fetch mode."""
- self.writecmd(self.MSP430APP,0xC1,0,self.data);
- return self.data[0];
- def MSP430ident(self):
- """Grab self-identification word from 0x0FF0 as big endian."""
- ident=0x00;
- if(self.JTAGID==0x89):
- i=self.MSP430peek(0x0ff0);
- ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
-
- if(self.JTAGID==0x91):
- i=self.MSP430peek(0x1A04);
- ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
- #ident=0x0091;
-
- return ident;
- def MSP430identstr(self):
- """Grab model string."""
- return self.MSP430devices.get(self.MSP430ident());
- MSP430devices={
- #MSP430F2xx
- 0xf227: "MSP430F22xx",
- 0xf213: "MSP430F21x1",
- 0xf249: "MSP430F24x",
- 0xf26f: "MSP430F261x",
- 0xf237: "MSP430F23x0",
-
-
- #MSP430F1xx
- 0xf16c: "MSP430F161x",
- 0xf149: "MSP430F13x", #or f14x(1)
- 0xf112: "MSP430F11x", #or f11x1
- 0xf143: "MSP430F14x",
- 0xf112: "MSP430F11x", #or F11x1A
- 0xf123: "MSP430F1xx", #or F123x
- 0x1132: "MSP430F1122", #or F1132
- 0x1232: "MSP430F1222", #or F1232
- 0xf169: "MSP430F16x",
-
- #MSP430F4xx
- 0xF449: "MSP430F43x", #or F44x
- 0xF427: "MSP430FE42x", #or FW42x, F415, F417
- 0xF439: "MSP430FG43x",
- 0xf46f: "MSP430FG46xx", #or F471xx
-
- }
- def MSP430test(self):
- """Test MSP430 JTAG. Requires that a chip be attached."""
-
- if self.MSP430ident()==0xffff:
- print "ERROR Is anything connected?";
- print "Testing %s." % self.MSP430identstr();
- print "Testing RAM from 200 to 210.";
- for a in range(0x200,0x210):
- self.MSP430poke(a,0);
- if(self.MSP430peek(a)!=0):
- print "Fault at %06x" % a;
- self.MSP430poke(a,0xffff);
- if(self.MSP430peek(a)!=0xffff):
- print "Fault at %06x" % a;
-
- print "Testing identity consistency."
- ident=self.MSP430ident();
- for a in range(1,20):
- ident2=self.MSP430ident();
- if ident!=ident2:
- print "Identity %04x!=%04x" % (ident,ident2);
-
- print "Testing flash erase."
- self.MSP430masserase();
- for a in range(0xffe0, 0xffff):
- if self.MSP430peek(a)!=0xffff:
- print "%04x unerased, equals %04x" % (
- a, self.MSP430peek(a));
-
- print "Testing flash write."
- for a in range(0xffe0, 0xffff):
- self.MSP430pokeflash(a,0xbeef);
- if self.MSP430peek(a)!=0xbeef:
- print "%04x unset, equals %04x" % (
- a, self.MSP430peek(a));
-
- print "Tests complete, erasing."
- self.MSP430masserase();
-
- def MSP430masserase(self):
- """Erase MSP430 flash memory."""
- self.writecmd(self.MSP430APP,0xE3,0,None);
- def MSP430setPC(self, pc):
- """Set the program counter."""
- self.writecmd(self.MSP430APP,0xC2,2,[pc&0xFF,(pc>>8)&0xFF]);
- def MSP430run(self):
- """Reset the MSP430 to run on its own."""
- self.writecmd(self.MSP430APP,0x21,0,None);
- def MSP430dumpbsl(self):
- self.MSP430dumpmem(0xC00,0xfff);
- def MSP430dumpallmem(self):
- self.MSP430dumpmem(0x200,0xffff);
- def MSP430dumpmem(self,begin,end):
- i=begin;
- while i<end:
- print "%04x %04x" % (i, self.MSP430peek(i));
- i+=2;
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET SPI and SPIFlash Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys, time, string, cStringIO, struct, glob, serial, os;
-
-from GoodFET import GoodFET;
-
-class GoodFETSPI(GoodFET):
- def SPIsetup(self):
- """Move the FET into the SPI application."""
- self.writecmd(0x01,0x10,0,self.data); #SPI/SETUP
-
- def SPItrans8(self,byte):
- """Read and write 8 bits by SPI."""
- data=self.SPItrans([byte]);
- return ord(data[0]);
-
- def SPItrans(self,data):
- """Exchange data by SPI."""
- self.data=data;
- self.writecmd(0x01,0x00,len(data),data);
- return self.data;
-
-class GoodFETSPIFlash(GoodFETSPI):
- JEDECmanufacturers={0xFF: "MISSING",
- 0xEF: "Winbond",
- 0xC2: "MXIC",
- 0x20: "Numonyx/ST",
- 0x1F: "Atmel",
- 0x01: "AMD/Spansion"
- };
-
- JEDECdevices={0xFFFFFF: "MISSING",
- 0xEF3015: "W25X16L",
- 0xEF3014: "W25X80L",
- 0xEF3013: "W25X40L",
- 0xEF3012: "W25X20L",
- 0xEF3011: "W25X10L",
- 0xC22017: "MX25L6405D",
- 0xC22016: "MX25L3205D",
- 0xC22015: "MX25L1605D",
- 0xC22014: "MX25L8005",
- 0xC22013: "MX25L4005",
- 0x204011: "M45PE10"
- };
-
- JEDECsizes={0x17: 0x800000,
- 0x16: 0x400000,
- 0x15: 0x200000,
- 0x14: 0x100000,
- 0x13: 0x080000,
- 0x12: 0x040000,
- 0x11: 0x020000
- };
-
- JEDECsize=0;
-
- def SPIjedec(self):
- """Grab an SPI Flash ROM's JEDEC bytes."""
- data=[0x9f, 0, 0, 0];
- data=self.SPItrans(data);
-
- self.JEDECmanufacturer=ord(data[1]);
- self.JEDECtype=ord(data[2]);
- self.JEDECcapacity=ord(data[3]);
- self.JEDECsize=self.JEDECsizes.get(self.JEDECcapacity);
- if self.JEDECsize==None:
- self.JEDECsize=0;
- self.JEDECdevice=(ord(data[1])<<16)+(ord(data[2])<<8)+ord(data[3]);
- return data;
- def SPIpeek(self,adr):
- """Grab a byte from an SPI Flash ROM."""
- data=[0x03,
- (adr&0xFF0000)>>16,
- (adr&0xFF00)>>8,
- adr&0xFF,
- 0];
- self.SPItrans(data);
- return ord(self.data[4]);
- def SPIpeekblock(self,adr):
- """Grab a few block from an SPI Flash ROM. Block size is unknown"""
- data=[(adr&0xFF0000)>>16,
- (adr&0xFF00)>>8,
- adr&0xFF];
-
- self.writecmd(0x01,0x02,3,data);
- return self.data;
-
- def SPIpokebyte(self,adr,val):
- self.SPIpokebytes(adr,[val]);
- def SPIpokebytes(self,adr,data):
- #Used to be 24 bits, BE, not 32 bits, LE.
- adranddata=[adr&0xFF,
- (adr&0xFF00)>>8,
- (adr&0xFF0000)>>16,
- 0, #MSB
- ]+data;
- #print "%06x: poking %i bytes" % (adr,len(data));
- self.writecmd(0x01,0x03,
- len(adranddata),adranddata);
-
- def SPIchiperase(self):
- """Mass erase an SPI Flash ROM."""
- self.writecmd(0x01,0x81);
- def SPIwriteenable(self):
- """SPI Flash Write Enable"""
- data=[0x06];
- self.SPItrans(data);
-
- def SPIjedecmanstr(self):
- """Grab the JEDEC manufacturer string. Call after SPIjedec()."""
- man=self.JEDECmanufacturers.get(self.JEDECmanufacturer)
- if man==0:
- man="UNKNOWN";
- return man;
-
- def SPIjedecstr(self):
- """Grab the JEDEC manufacturer string. Call after SPIjedec()."""
- man=self.JEDECmanufacturers.get(self.JEDECmanufacturer);
- if man==0:
- man="UNKNOWN";
- device=self.JEDECdevices.get(self.JEDECdevice);
- if device==0:
- device="???"
- return "%s %s" % (man,device);
-
+++ /dev/null
-#!/usr/bin/env python
-# GoodFET SPI and SPIFlash Client Library
-#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
-#
-# This code is being rewritten and refactored. You've been warned!
-
-import sys, time, string, cStringIO, struct, glob, serial, os;
-
-from GoodFET import GoodFET;
-
-class GoodFETSmartCard(GoodFET):
- SMARTCARDAPP=0x73;
- APP=SMARTCARDAPP;
-
- def setup(self):
- """Move the FET into the SmartCard application."""
- self.writecmd(self.APP,0x10,0,self.data);
- def start(self):
- """Start the connection, reat ATR."""
- self.writecmd(self.APP,0x20,0,None);
import sys, os, readline, code, binascii;
import rlcompleter;
-from GoodFETConsole import GoodFETConsole;
-from GoodFETCC import GoodFETCC;
-from GoodFETMSP430 import GoodFETMSP430;
-from GoodFET import GoodFET;
+import GoodFET;
+from GoodFET.GoodFETConsole import GoodFETConsole;
+#from GoodFET import *;
from intelhex import IntelHex;
driver=sys.argv[1];
print "Using driver %s" % driver;
-client=eval("%s()" % driver);
-console=GoodFETConsole(client);
+#client=eval("%s()" % driver);
+client=GoodFET.getClient(driver);
+console=client.getConsole();
console.run();
sys.exit(0);
import sys;
import binascii;
-from GoodFETAVR import GoodFETAVR;
+from GoodFET.GoodFETAVR import GoodFETAVR;
from intelhex import IntelHex16bit, IntelHex;
if(len(sys.argv)==1):
import sys;
import binascii;
-from GoodFETCC import GoodFETCC;
-from GoodFETConsole import GoodFETConsole;
-from intelhex import IntelHex;
+from GoodFET.GoodFETCC import GoodFETCC;
if(len(sys.argv)==1):
sys.exit();
#Initailize FET and set baud rate
+#client=GoodFET.GoodFETCC.GoodFETCC();
client=GoodFETCC();
client.serInit()
+++ /dev/null
-#!/usr/bin/env python
-
-#GoodFET I2C EEPROM Client
-#by Travis Goodspeed
-
-import sys;
-import binascii;
-import array;
-
-from GoodFET import GoodFET;
-from intelhex import IntelHex;
-
-if(len(sys.argv)==1):
- print "Usage: %s verb [objects]\n" % sys.argv[0];
- print "%s info" % sys.argv[0];
- print "%s dump $foo.hex [0x$start 0x$stop]" % sys.argv[0];
- print "%s erase" % sys.argv[0];
- print "%s write $foo.hex [0x$start 0x$stop]" % sys.argv[0];
- print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0];
- print "%s peek 0x$start [0x$stop]" % sys.argv[0];
- print "%s poke 0x$adr 0x$val" % sys.argv[0];
- sys.exit();
-
-#Initailize FET and set baud rate
-client=GoodFET();
-client.serInit()
-
-
-client.I2Csetup();
-
-#Dummy read.
-#Might read as all ones if chip has a startup delay.
-#client.SPIjedec();
-
-if(sys.argv[1]=="foo"):
- client.I2Cstart();
-
- # Write AA55 at 0x00
- #print "%i" % client.I2Cwrite([0xA0, 0x00, 0x00, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55]);
- client.I2Cstop();
-
- client.I2Cstart();
- print "%i" % client.I2Cwrite([0xA0, 0x00, 0x00]); # Set ADR=0x00
- client.I2Cstart();#restart
- print "%i" % client.I2Cwrite([0xA1]); # Set ADR=0x00
- data=client.I2Cread(128);
- s="";
- for d in data:
- s+="%02x " % ord(d);
- print s
- client.I2Cstop();
-
-
-if(sys.argv[1]=="test"):
- result="";
- dropped=0;
- for i in range(40):
- data=client.SPIjedec();
- if ord(data[1])==0xFF:
- result+="-";
- dropped=dropped+1;
- else:
- result+="+";
- print "Connection Test: (- is bad)\n%s" % result;
- print "%i misreads" % dropped;
- if(dropped==40):
- print "No successful reads. Is the chip wired correctly?";
- elif(dropped>0):
- print "Some success, some failures. Is a wire loose?";
- else:
- print "All reads succeeded. Wiring is probably good.";
-
-if(sys.argv[1]=="info"):
- data=client.SPIjedec();
- print "Ident as %s\nManufacturer: %02x %s\nType: %02x\nCapacity: %02x" % (
- client.SPIjedecstr(),
- ord(data[1]),client.SPIjedecmanstr(),
- ord(data[2]),
- ord(data[3]));
-
-if(sys.argv[1]=="dump"):
- f = sys.argv[2];
- start=0x0000;
- stop=0x100000; #TODO, adjust this by the JEDEC size parameter.
- if(len(sys.argv)>3):
- start=int(sys.argv[3],16);
- if(len(sys.argv)>4):
- stop=int(sys.argv[4],16);
-
- print "Dumping code from %06x to %06x as %s." % (start,stop,f);
- file = open(f, mode='wb')
-
- i=start;
- while i<=stop:
- data=client.SPIpeekblock(i);
- if(i%0x1000==0):
- print "Dumped %06x."%i;
- for j in data:
- file.write(j);
- i+=1;
- file.close()
-if(sys.argv[1]=="flash"):
- f = sys.argv[2];
- start=0x0000;
- stop=0x100000; #TODO, adjust this by the JEDEC size parameter.
- if(len(sys.argv)>3):
- start=int(sys.argv[3],16);
- if(len(sys.argv)>4):
- stop=int(sys.argv[4],16);
-
- print "Flashing code from %06x to %06x with %s." % (start,stop,f);
- file = open(f, mode='rb')
-
- i=start;
- chars=list(file.read());
- chunksize=0x80;
-
- while i<=stop:
- bytes=range(0,chunksize);
- for j in range(0,chunksize):
- bytes[j]=ord(chars[i+j]);
- #client.SPIpokebyte(i,ord(chars[i]));
- client.SPIpokebytes(i,bytes);
-
- i+=chunksize;
- if(i%0x100==0):
- print "Flashed %06x."%i;
- file.close()
-
-
-if(sys.argv[1]=="erase"):
- client.SPIchiperase();
-
-if(sys.argv[1]=="peek"):
- start=0x0000;
- if(len(sys.argv)>2):
- start=int(sys.argv[2],16);
- stop=start;
- if(len(sys.argv)>3):
- stop=int(sys.argv[3],16);
- print "Peeking from %06x to %06x." % (start,stop);
- while start<=stop:
- print "%06x: %02x" % (start,client.SPIpeek(start));
- start=start+1;
-
-if(sys.argv[1]=="poke"):
- start=0x0000;
- val=0x00;
- if(len(sys.argv)>2):
- start=int(sys.argv[2],16);
- if(len(sys.argv)>3):
- val=int(sys.argv[3],16);
- print "Poking %06x to become %02x." % (start,val);
-
- while client.SPIpeek(start)!=val:
- client.SPIpokebyte(start,val);
- print "Poked to %02x" % client.SPIpeek(start);
-
import sys;
import binascii;
-from GoodFET import GoodFET;
+from GoodFET.GoodFET import GoodFET;
from intelhex import IntelHex16bit;
if(len(sys.argv)==1):
import sys;
import binascii;
-from GoodFETMSP430 import GoodFETMSP430;
+from GoodFET.GoodFETMSP430 import GoodFETMSP430;
from intelhex import IntelHex16bit, IntelHex;
-
if(len(sys.argv)==1):
print "Usage: %s verb [objects]\n" % sys.argv[0];
print "%s test" % sys.argv[0];
import sys;
import binascii;
-from GoodFETSmartCard import GoodFETSmartCard;
+from GoodFET.GoodFETSmartCard import GoodFETSmartCard;
from intelhex import IntelHex16bit, IntelHex;
#Initialize FET and set baud rate
import binascii;
import array;
-from GoodFETSPI import GoodFETSPIFlash;
+from GoodFET.GoodFETSPI import GoodFETSPIFlash;
from intelhex import IntelHex;
if(len(sys.argv)==1):