X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFET.py;h=18a3eb1a952ec1a6eb73707ef1e9d184438875aa;hp=94737bad884f07ea1f82f0f63e16645212b5440e;hb=f4a6b415e762bcdc560f3ea655851d16f483ea5a;hpb=81b8a55948335302b9691eff6b71ef17d61c61d5 diff --git a/client/GoodFET.py b/client/GoodFET.py index 94737ba..18a3eb1 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -3,21 +3,33 @@ # # (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 -sys.path.append("/usr/lib/tinyos") -import serial +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): - print "timout\n"; - def serInit(self, port): + 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, @@ -33,28 +45,72 @@ class GoodFET: #time.sleep(1); self.readcmd(); #Read the first command. if(self.verb!=0x7F): - print "Verb is wrong. Incorrect firmware?"; - - def writecmd(self, app, verb, count, data): + 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)); - self.serialport.write(chr(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: for d in data: self.serialport.write(chr(d)); - self.readcmd(); #Uncomment this later, to ensure a response. + + #self.serialport.flushOutput(); + #self.serialport.flushInput(); + + + 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)); - if self.count>0: - self.data=self.serialport.read(self.count); - #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]; @@ -69,8 +125,30 @@ class GoodFET: 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>8]; - self.writecmd(0x11,0x02,2,self.data); - return ord(self.data[0])+(ord(self.data[1])<<8); - 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 CCwr_config(self,config): + """Write the config register of a Chipcon.""" + self.writecmd(0x30,0x81,1,[config&0xFF]); - def MSP430start(self): + 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(0x11,0x20,0,self.data); - ident=self.MSP430ident(); - print "Target identifies as %04x." % ident; + 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 MSP430stop(self): + def CCstop(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); + self.writecmd(0x30,0x21,0,self.data); + def CCstep_instr(self): + """Step one instruction.""" + self.writecmd(0x30,0x89,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