From 9e13b1450d770a5645468221d0eacc1533d654a9 Mon Sep 17 00:00:00 2001 From: travisutk Date: Thu, 16 Jul 2009 18:31:49 +0000 Subject: [PATCH] Dumping of SPI Flash ROMs works, at least for Winbond. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@63 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFET.py | 69 +++++++++++++++++++++----- client/goodfet.spiflash | 104 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 11 deletions(-) create mode 100755 client/goodfet.spiflash diff --git a/client/GoodFET.py b/client/GoodFET.py index cb36031..9c11161 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -7,7 +7,7 @@ # Rewrite cleanly as soon as is convenient. import sys, time, string, cStringIO, struct -sys.path.append("/usr/lib/tinyos") +#sys.path.append("/usr/lib/tinyos") import serial @@ -99,23 +99,70 @@ class GoodFET: print "Self-test complete."; - def spisetup(self): + def SPIsetup(self): """Moved the FET into the SPI application.""" - self.writecmd(1,0x10,0,self.data); #SPI/SETUP + self.writecmd(0x01,0x10,0,self.data); #SPI/SETUP #self.readcmd(); - def spitrans8(self,byte): + def SPItrans8(self,byte): """Read and write 8 bits by SPI.""" - self.data=[byte]; - self.writecmd(1,0,1,self.data); #SPI exchange - #self.readcmd(); - - if self.app!=1 or self.verb!=0: - print "Error in SPI transaction; app=%02x, verb=%02x" % (self.app, self.verb); - return ord(self.data[0]); + 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; + + JEDECmanufacturers={0xFF: "MISSING", + 0xEF: "Winbond"}; + JEDECdevices={0xEF3014: "W25X80L", + 0xEF3013: "W25X40L", + 0xEF3012: "W25X20L", + 0xEF3011: "W25X10L"}; + def SPIjedec(self): + """Grab an SPI Flash ROM's JEDEC bytes.""" + data=[0x9f, 0, 0, 0]; + data=self.SPItrans(data); + #print "Manufacturer: %02x\nType: %02x\nCapacity: %02x" % (ord(data[1]),ord(data[2]),ord(data[3])); + self.JEDECmanufacturer=ord(data[1]); + self.JEDECtype=ord(data[2]); + self.JEDECcapacity=ord(data[3]); + 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 SPIjedecmanstr(self): + """Grab the JEDEC manufacturer string. Call after SPIjedec().""" + man=self.JEDECmanufacturers[self.JEDECmanufacturer]; + if man==0: + man="UNKNOWN"; + return man; + + def SPIjedecstr(self): + """Grab the JEDEC manufacturer string. Call after SPIjedec().""" + man=self.JEDECmanufacturers[self.JEDECmanufacturer]; + if man==0: + man="UNKNOWN"; + device=self.JEDECdevices[self.JEDECdevice]; + if device==0: + device="???" + return "%s %s" % (man,device); def MSP430setup(self): """Move the FET into the MSP430 JTAG application.""" print "Initializing MSP430."; self.writecmd(0x11,0x10,0,self.data); + + + def CCsetup(self): """Move the FET into the CC2430/CC2530 application.""" print "Initializing Chipcon."; diff --git a/client/goodfet.spiflash b/client/goodfet.spiflash new file mode 100755 index 0000000..ef72c28 --- /dev/null +++ b/client/goodfet.spiflash @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +#GoodFET SPI Flash Client +#by Travis Goodspeed + +#N.B., +#Might be Winbond W25x80-specific. + +import sys; +import binascii; + +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("/dev/ttyUSB0") + +client.SPIsetup(); + +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=0xFFFF; + 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 %04x to %04x as %s." % (start,stop,f); + h = IntelHex(None); + i=start; + while i<=stop: + h[i>>1]=client.SPIpeek(i); + if(i%0x100==0): + print "Dumped %04x."%i; + i+=1; + h.write_hex_file(f); + +if(sys.argv[1]=="erase"): + print "Status: %s" % client.CCstatusstr(); + client.CCchiperase(); + print "Status: %s" %client.CCstatusstr(); + +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 %04x to %04x." % (start,stop); + while start<=stop: + print "%04x: %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 %04x to become %02x." % (start,val); +# client.CCpokedatabyte(start,val); + + -- 2.20.1