X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFET.py;h=da652c3a447c797aaa32f91b20b327c2c328dcf5;hp=3b4d9e788f4ca2e58913a403a7209bd559ece207;hb=43d125b5bca16f0941450bee6ba7bd94ab41dc72;hpb=412f5e22fe35d4aed40d3a145f1d9213d42d23f9 diff --git a/client/GoodFET.py b/client/GoodFET.py index 3b4d9e7..da652c3 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -36,6 +36,9 @@ class GoodFET: 115200, parity = serial.PARITY_NONE ) + + #Explicitly set RTS + self.serialport.setRTS(1); #Drop DTR, which is !RST, low to begin the app. self.serialport.setDTR(0); self.serialport.flushInput() @@ -47,27 +50,74 @@ class GoodFET: if(self.verb!=0x7F): print "Verb %02x is wrong. Incorrect firmware?" % self.verb; #print "Connected." - def writecmd(self, app, verb, count=0, 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=[]): """Write a command and some data to the GoodFET.""" self.serialport.write(chr(app)); self.serialport.write(chr(verb)); - self.serialport.write(chr(count)); + + #if data!=None: + # count=len(data); #Initial count ignored. + + #print "TX %02x %02x" % (app,verb); + + #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: - for d in data: - self.serialport.write(chr(d)); - self.readcmd(blocks); #Uncomment this later, to ensure a response. - def readcmd(self,blocks=1): + if count!=0: + for i in range(0,count): + #print "Converting %02x at %i" % (data[i],i) + data[i]=chr(data[i]); + outstr=''.join(data); + #outstr=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.""" - 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: + #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); + else: + self.data=self.serialport.read(self.count); + 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]; @@ -168,245 +218,3 @@ class GoodFET: """Write bytes by I2C.""" self.writecmd(0x02,0x01,len(bytes),bytes); #SPI/SETUP return ord(self.data[0]); -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" - }; - - 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,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); - -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."; - self.writecmd(0x30,0x10,0,self.data); - def CCrd_config(self): - """Read the config register of a Chipcon.""" - self.writecmd(0x30,0x82,0,self.data); - return ord(self.data[0]); - def CCwr_config(self,config): - """Write the config register of a Chipcon.""" - self.writecmd(0x30,0x81,1,[config&0xFF]); - - CCversions={0x0100:"CC1110", - 0x8500:"CC2430", - 0x8900:"CC2431", - 0x8100:"CC2510", - 0x9100:"CC2511", - 0xFF00:"CCmissing"}; - 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(0x30,0x8B,0,None); - chip=ord(self.data[0]); - rev=ord(self.data[1]); - return (chip<<8)+rev; - def CCgetPC(self): - """Get a chipcon's PC.""" - self.writecmd(0x30,0x83,0,None); - hi=ord(self.data[0]); - lo=ord(self.data[1]); - return (hi<<8)+lo; - def CCdebuginstr(self,instr): - self.writecmd(0x30,0x88,len(instr),instr); - return ord(self.data[0]); - def CCpeekcodebyte(self,adr): - """Read the contents of code memory at an address.""" - self.data=[adr&0xff, (adr&0xff00)>>8]; - self.writecmd(0x30,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(0x30,0x91, 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(0x30, 0x92, 3, self.data); - return ord(self.data[0]); - def CCchiperase(self): - """Erase all of the target's memory.""" - self.writecmd(0x30,0x80,0,None); - def CCstatus(self): - """Check the status.""" - self.writecmd(0x30,0x84,0,None); - return ord(self.data[0]) - CCstatusbits={0x80 : "erased", - 0x40 : "pcon_idle", - 0x20 : "halted", - 0x10 : "pm0", - 0x08 : "halted", - 0x04 : "locked", - 0x02 : "oscstable", - 0x01 : "overflow"}; - def CCstatusstr(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 CCstart(self): - """Start debugging.""" - self.writecmd(0x30,0x20,0,self.data); - ident=self.CCidentstr(); - print "Target identifies as %s." % ident; - #print "Status: %s." % self.CCstatusstr(); - self.CCreleasecpu(); - self.CChaltcpu(); - #print "Status: %s." % self.CCstatusstr(); - - def CCstop(self): - """Stop debugging.""" - self.writecmd(0x30,0x21,0,self.data); - def CCstep_instr(self): - """Step one instruction.""" - self.writecmd(0x30,0x89,0,self.data); -