X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFET.py;h=11ca61646a36d30f84f93e585a8c176a92d87cc9;hp=031a33d4ab4f82e2a25d110f983856452adfdbc9;hb=f3f96e7ef9e9fd6fe27360651e3c2142ac1eae8c;hpb=378b4719313e80afca07c8b746ee90fe85cecaf0 diff --git a/client/GoodFET.py b/client/GoodFET.py index 031a33d..11ca616 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -50,33 +50,54 @@ class SymbolTable: #print "Set %s=%s." % (name,adr); class GoodFETbtser: """py-bluez class for emulating py-serial.""" - def __init__(self,watchaddr): + def __init__(self,btaddr): import bluetooth; - while watchaddr==None or watchaddr=="none": + if btaddr==None or btaddr=="none" or btaddr=="bluetooth": print "performing inquiry..." nearby_devices = bluetooth.discover_devices(lookup_names = True) print "found %d devices" % len(nearby_devices) for addr, name in nearby_devices: print " %s - '%s'" % (addr, name) + #TODO switch to wildcards. if name=='FireFly-A6BD': - watchaddr=addr; - print "Identified GoodFET at %s" % watchaddr; + btaddr=addr; + if name=='RN42-A94A': + btaddr=addr; + + print "Please set $GOODFET to the address of your device."; + sys.exit(); + print "Identified GoodFET at %s" % btaddr; - # BlueFET doesn't run the Service Discovery Protocol. - # Instead we manually use the portnumber. + # Manually use the portnumber. port=1; - print "Connecting to %s on port %i." % (watchaddr, port); + print "Connecting to %s on port %i." % (btaddr, port); sock=bluetooth.BluetoothSocket(bluetooth.RFCOMM); self.sock=sock; - sock.connect((watchaddr,port)); + sock.connect((btaddr,port)); sock.settimeout(10); #IMPORTANT Must be patient. + + ##This is what we'd do for a normal reset. + #str=""; + #while not str.endswith("goodfet.sf.net/"): + # str=self.read(64); + # print str; + + # Instead, just return and hope for the best. + return; + def write(self,msg): """Send traffic.""" - return self.sock.send(msg); - def read(self,len): + import time; + self.sock.send(msg); + #time.sleep(0.1); + return; + def read(self,length): """Read traffic.""" - return self.sock.recv(len); + data=""; + while len(data)= attemptlimit: return - elif attempts>2: - print "Resyncing."; - self.serialport.flushInput() - self.serialport.flushOutput() + elif attempts==2 and os.environ.get("board")!='telosb': + print "See the GoodFET FAQ about missing info flash."; + self.serialport.setTimeout(0.2); + #self.serialport.flushInput() + #self.serialport.flushOutput() #TelosB reset, prefer software to I2C SPST Switch. - if(os.environ.get("platform")=='telosb'): + if (os.environ.get("board")=='telosb'): #print "TelosB Reset"; self.telosBReset(); + elif (os.environ.get("board")=='z1'): + self.bslResetZ1(invokeBSL=0); + elif (os.environ.get("board")=='apimote1') or (os.environ.get("board")=='apimote'): + #Explicitly set RTS and DTR to halt board. + self.serialport.setRTS(1); + self.serialport.setDTR(1); + #RTS pin, not DTR is used for reset. + self.serialport.setRTS(0); + #print "Resetting Apimote not yet tested."; else: #Explicitly set RTS and DTR to halt board. self.serialport.setRTS(1); @@ -194,19 +233,22 @@ class GoodFET: attempts=attempts+1; self.readcmd(); #Read the first command. #print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data); + if self.verb!=0x7f: + #Retry again. This usually times out, but helps connect. + self.readcmd(); + #print "Retry got %02x,%02x:'%s'" % (self.app,self.verb,self.data); #Here we have a connection, but maybe not a good one. #print "We have a connection." connected=1; olds=self.infostring(); clocking=self.monitorclocking(); - #if(os.environ.get("platform")!='arduino'): for foo in range(1,30): if not self.monitorecho(): if self.verbose: print "Comm error on %i try, resyncing out of %s." % (foo, clocking); - connected=0; - break; + connected=0; + break; if self.verbose: print "Connected after %02i attempts." % attempts; self.mon_connected(); self.serialport.setTimeout(12); @@ -251,6 +293,82 @@ class GoodFET: self.telosI2CWriteByte( 0x90 | (addr << 1) ) self.telosI2CWriteByte( cmdbyte ) self.telosI2CStop() + def bslResetZ1(self, invokeBSL=0): + ''' + Applies BSL entry sequence on RST/NMI and TEST/VPP pins + Parameters: + invokeBSL = 1: complete sequence + invokeBSL = 0: only RST/NMI pin accessed + + By now only BSL mode is accessed + ''' + + #if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) + if invokeBSL: + #sys.stderr.write("in Z1 bsl reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFF) + time.sleep(0.1) + #sys.stderr.write("z1 bsl reset done...\n") + else: + #sys.stderr.write("in Z1 reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFE) + time.sleep(0.1) + #sys.stderr.write("z1 reset done...\n") + def writepicROM(self, address, data): + ''' Writes data to @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(0) + recbuf = 0 + for i in range(7,-1,-1): + s = ((data >> i) & 0x01) + #print s + if i < 1: + r = not self.picROMclock(s, True) + else: + r = not self.picROMclock(s) + recbuf = (recbuf << 1) + r + + self.picROMclock(0, True) + #k = 1 + #while not self.serial.getCTS(): + # pass + #time.sleep(0.1) + return recbuf + def readpicROM(self, address): + ''' reads a byte from @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(1) + recbuf = 0 + r = 0 + for i in range(7,-1,-1): + r = self.picROMclock(0) + recbuf = (recbuf << 1) + r + self.picROMclock(r) + #time.sleep(0.1) + return recbuf + + #This seems more reliable when slowed. + def picROMclock(self, masterout, slow = True): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + #time.sleep(0.02) + self.serialport.setDTR(0) + if slow: + time.sleep(0.02) + return self.serialport.getCTS() + + def picROMfastclock(self, masterout): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + self.serialport.setDTR(0) + time.sleep(0.02) + return self.serialport.getCTS() def telosBReset(self,invokeBSL=0): # "BSL entry sequence at dedicated JTAG pins" @@ -336,8 +454,8 @@ class GoodFET: +(ord(self.serialport.read(1))<<8) ); - #if self.verbose: - #print "Rx: ( 0x%02x, 0x%02x, 0x%04x )" % ( self.app, self.verb, self.count ) + if self.verbose: + print "Rx: ( 0x%02x, 0x%02x, 0x%04x )" % ( self.app, self.verb, self.count ) #Debugging string; print, but wait. if self.app==0xFF: @@ -457,6 +575,9 @@ class GoodFET: self.writecmd(0,0x03,3,self.data); return ord(self.data[0]); def poke16(self,address,value): + """Set a word of memory by the monitor.""" + self.MONpoke16(address,value); + def MONpoke16(self,address,value): """Set a word of memory by the monitor.""" self.pokebyte(address,value&0xFF); self.pokebyte(address,(value>>8)&0xFF); @@ -550,7 +671,8 @@ class GoodFET: data="The quick brown fox jumped over the lazy dog."; self.writecmd(self.MONITORAPP,0x81,len(data),data); if self.data!=data: - print "Comm error recognized by monitorecho(), got:\n%s" % self.data; + if self.verbose: + print "Comm error recognized by monitorecho(), got:\n%s" % self.data; return 0; return 1; @@ -559,6 +681,15 @@ class GoodFET: print "Clocked at %s" % self.monitorclocking(); return 1; + def testleds(self): + print "Flashing LEDs" + self.writecmd(self.MONITORAPP,0xD0,0,"") + try: + print "Flashed %d LED." % ord(self.data) + except: + print "Unable to process response:", self.data + return 1 + def monitor_list_apps(self, full=False): self.monitor_info() old_value = self.besilent @@ -586,7 +717,7 @@ class GoodFET: self.MONpoke16(0x56, clock); def monitorgetclock(self): """Get the clocking value.""" - if(os.environ.get("platform")=='arduino'): + if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'): return 0xDEAD; #Check for MSP430 before peeking this. return self.MONpeek16(0x56); @@ -594,7 +725,7 @@ class GoodFET: # every client. def infostring(self): - if(os.environ.get("platform")=='arduino'): + if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'): return "Arduino"; else: a=self.MONpeek8(0xff0);