X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFET.py;h=af24201cbcd74b8db97c041bdc157678e7487484;hp=5a7ab02de3c34678f6841d2ab0c43744bcfa7f40;hb=1706a7f4cfa73ed716b56f5b0322bfb67b560ade;hpb=cfe184370a5358f450773cc34f3c67ca2f20f391 diff --git a/client/GoodFET.py b/client/GoodFET.py index 5a7ab02..af24201 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -3,13 +3,13 @@ # # (C) 2009 Travis Goodspeed # -# This code is ugly as sin, for bootstrapping the firmware only. -# Rewrite cleanly as soon as is convenient. +# 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""" def __init__(self, *args, **kargs): self.data=[0]; def timeout(self): @@ -47,7 +47,10 @@ class GoodFET: if(self.verb!=0x7F): print "Verb %02x is wrong. Incorrect firmware?" % self.verb; #print "Connected." - def writecmd(self, app, verb, count, data=[], blocks=1): + 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=[], blocks=1): """Write a command and some data to the GoodFET.""" self.serialport.write(chr(app)); self.serialport.write(chr(verb)); @@ -57,17 +60,45 @@ class GoodFET: for d in data: self.serialport.write(chr(d)); - self.readcmd(blocks); #Uncomment this later, to ensure a response. + if not self.besilent: + #print "Reading reply to %02x/%02x." % (app,verb); + self.readcmd(blocks); + #print "Read reply." + + besilent=0; + app=0; + verb=0; + count=0; + data=""; + def readcmd(self,blocks=1): """Read a reply from the GoodFET.""" - self.app=ord(self.serialport.read(1)); - self.verb=ord(self.serialport.read(1)); - self.count=ord(self.serialport.read(1)); - self.data=self.serialport.read(self.count*blocks); - return self.data; - #print "READ %02x %02x %02x " % (self.app, self.verb, self.count); - + while 1: + self.app=ord(self.serialport.read(1)); + self.verb=ord(self.serialport.read(1)); + self.count=ord(self.serialport.read(1)); + self.data=self.serialport.read(self.count*blocks); + #print "READ %02x %02x %02x " % (self.app, self.verb, self.count); + + #Debugging string; print, but wait. + if self.app==0xFF and self.verb==0xFF: + print "DEBUG %s" % self.data; + else: + return self.data; + #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 peekbyte(self,address): """Read a byte of memory from the monitor.""" self.data=[address&0xff,address>>8]; @@ -149,121 +180,7 @@ class GoodFET: print "Self-test complete."; - def SPIsetup(self): - """Moved 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; - - JEDECmanufacturers={0xFF: "MISSING", - 0xEF: "Winbond", - 0xC2: "MXIC", - 0x20: "Numonyx/ST" - }; - - JEDECdevices={0xFFFFFF: "MISSING", - 0xEF3014: "W25X80L", - 0xEF3013: "W25X40L", - 0xEF3012: "W25X20L", - 0xEF3011: "W25X10L", - 0xC22014: "MX25L8005", - 0xC22013: "MX25L4005", - 0x204011: "M45PE10" - }; - JEDECsizes={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); - #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.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 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 SPIpeekblock(self,adr,blocks=1): - """Grab a few block from an SPI Flash ROM. Block size is unknown""" - data=[(adr&0xFF0000)>>16, - (adr&0xFF00)>>8, - adr&0xFF, - blocks]; - - self.writecmd(0x01,0x02,4,data,blocks); - return self.data; - - def SPIpokebyte(self,adr,val): - self.SPIpokebytes(adr,[val]); - def SPIpokebytes(self,adr,data): - #self.SPIwriteenable(); - adranddata=[(adr&0xFF0000)>>16, - (adr&0xFF00)>>8, - adr&0xFF - ]+data; - self.writecmd(0x01,0x03, - len(adranddata),adranddata); - - def SPIchiperase(self): - """Mass erase an SPI Flash ROM.""" - self.writecmd(0x01,0x81,0,[]); - 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); - def MSP430setup(self): - """Move the FET into the MSP430 JTAG application.""" - print "Initializing MSP430."; - self.writecmd(0x11,0x10,0,self.data); def I2Csetup(self): """Move the FET into the I2C application.""" @@ -282,6 +199,48 @@ class GoodFET: """Write bytes by I2C.""" self.writecmd(0x02,0x01,len(bytes),bytes); #SPI/SETUP return ord(self.data[0]); +class GoodFETCC(GoodFET): + """A GoodFET variant for use with Chipcon 8051 Zigbe SoC.""" + def CChaltcpu(self): + """Halt the CPU.""" + self.writecmd(0x30,0x86,0,self.data); + def CCreleasecpu(self): + """Resume the CPU.""" + self.writecmd(0x30,0x87,0,self.data); + def CCtest(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 "Status: %s." % self.CCstatusstr(); + #Exit debugger + self.CCstop(); + print "Done."; + def CCsetup(self): """Move the FET into the CC2430/CC2530 application.""" #print "Initializing Chipcon."; @@ -319,11 +278,6 @@ class GoodFET: def CCdebuginstr(self,instr): self.writecmd(0x30,0x88,len(instr),instr); return ord(self.data[0]); - def MSP430peek(self,adr): - """Read the contents of memory at an address.""" - self.data=[adr&0xff, (adr&0xff00)>>8]; - self.writecmd(0x11,0x02,2,self.data); - return ord(self.data[0])+(ord(self.data[1])<<8); def CCpeekcodebyte(self,adr): """Read the contents of code memory at an address.""" self.data=[adr&0xff, (adr&0xff00)>>8]; @@ -364,17 +318,6 @@ class GoodFET: str="%s %s" %(self.CCstatusbits[i],str); i*=2; return str; - def MSP430poke(self,adr,val): - """Read the contents of memory at an address.""" - self.data=[adr&0xff, (adr&0xff00)>>8, val&0xff, (val&0xff00)>>8]; - self.writecmd(0x11,0x03,4,self.data); - return;# ord(self.data[0])+(ord(self.data[1])<<8); - def MSP430start(self): - """Start debugging.""" - self.writecmd(0x11,0x20,0,self.data); - ident=self.MSP430ident(); - print "Target identifies as %04x." % ident; - def CCstart(self): """Start debugging.""" self.writecmd(0x30,0x20,0,self.data); @@ -391,110 +334,4 @@ class GoodFET: def CCstep_instr(self): """Step one instruction.""" self.writecmd(0x30,0x89,0,self.data); - def MSP430stop(self): - """Stop debugging.""" - self.writecmd(0x11,0x21,0,self.data); - def MSP430haltcpu(self): - """Halt the CPU.""" - self.writecmd(0x11,0xA0,0,self.data); - def MSP430releasecpu(self): - """Resume the CPU.""" - self.writecmd(0x11,0xA1,0,self.data); - def CChaltcpu(self): - """Halt the CPU.""" - self.writecmd(0x30,0x86,0,self.data); - def CCreleasecpu(self): - """Resume the CPU.""" - self.writecmd(0x30,0x87,0,self.data); - def MSP430shiftir8(self,ins): - """Shift the 8-bit Instruction Register.""" - data=[ins]; - self.writecmd(0x11,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(0x11,0x81,2,data); - return ord(self.data[0])#+(ord(self.data[1])<<8); - def MSP430setinstrfetch(self): - """Set the instruction fetch mode.""" - self.writecmd(0x11,0xC1,0,self.data); - return self.data[0]; - def MSP430ident(self): - """Grab self-identification word from 0x0FF0 as big endian.""" - i=self.MSP430peek(0x0ff0); - return ((i&0xFF00)>>8)+((i&0xFF)<<8) - def MSP430test(self): - """Test MSP430 JTAG. Requires that a chip be attached.""" - if self.MSP430ident()==0xffff: - print "Is anything connected?"; - print "Testing RAM."; - temp=self.MSP430peek(0x0200); - self.MSP430poke(0x0200,0xdead); - if(self.MSP430peek(0x0200)!=0xdead): - print "Poke of 0x0200 did not set to 0xDEAD properly."; - return; - self.MSP430poke(0x0200,temp); #restore old value. - def MSP430flashtest(self): - self.MSP430masserase(); - i=0x2500; - while(i<0xFFFF): - if(self.MSP430peek(i)!=0xFFFF): - print "ERROR: Unerased flash at %04x."%i; - self.MSP430writeflash(i,0xDEAD); - i+=2; - def MSP430masserase(self): - """Erase MSP430 flash memory.""" - self.writecmd(0x11,0xE3,0,None); - def MSP430writeflash(self,adr,val): - """Write a word of flash memory.""" - if(self.MSP430peek(adr)!=0xFFFF): - print "FLASH ERROR: %04x not clear." % adr; - data=[adr&0xFF,(adr&0xFF00)>>8,val&0xFF,(val&0xFF00)>>8]; - self.writecmd(0x11,0xE1,4,data); - rval=ord(self.data[0])+(ord(self.data[1])<<8); - if(val!=rval): - print "FLASH WRITE ERROR AT %04x. Found %04x, wrote %04x." % (adr,rval,val); - - def MSP430dumpbsl(self): - self.MSP430dumpmem(0xC00,0xfff); - def MSP430dumpallmem(self): - self.MSP430dumpmem(0x200,0xffff); - def MSP430dumpmem(self,begin,end): - i=begin; - while i