From 0c3db8ce9f40190ec063347e21ed382d5486cb67 Mon Sep 17 00:00:00 2001 From: travisutk Date: Tue, 14 Aug 2012 20:29:57 +0000 Subject: [PATCH] Lots of new CC2420 stabilization. 'goodfet.ccspi surf' for channel surfing. 'goodfet.ccspi spectrum' for cheap spectrum analysis. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1222 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFET.py | 17 ++++++--- client/GoodFETCCSPI.py | 24 +++++++----- client/Makefile | 3 +- client/goodfet.ccspi | 71 +++++++++++++++++++++++++++++++++++- firmware/apps/radios/ccspi.c | 24 +++++++++--- 5 files changed, 116 insertions(+), 23 deletions(-) diff --git a/client/GoodFET.py b/client/GoodFET.py index 23a147f..05c2045 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -128,7 +128,7 @@ class GoodFET: if port==None: port=os.environ.get("GOODFET"); if port=="bluetooth" or (port is not None and re.match("..:..:..:..:..:..",port)): - self.btInit(port,timeout,attemptlimit); + self.btInit(port,2,attemptlimit); else: self.pyserInit(port,timeout,attemptlimit); def btInit(self, port, timeout, attemptlimit): @@ -195,16 +195,16 @@ class GoodFET: if attemptlimit is not None and attempts >= attemptlimit: return elif attempts>2: - print "Resyncing."; - self.serialport.flushInput() - self.serialport.flushOutput() + print "Resyncing. See the GoodFET FAQ about missing info flash."; + #self.serialport.flushInput() + #self.serialport.flushOutput() #TelosB reset, prefer software to I2C SPST Switch. if (os.environ.get("platform")=='telosb' or os.environ.get("board")=='telosb'): #print "TelosB Reset"; self.telosBReset(); elif (os.environ.get("board")=='zolertiaz1' or os.environ.get("board")=='z1'): - self.bslResetZ1(); + self.bslResetZ1(invokeBSL=0); elif (os.environ.get("board")=='apimote1'): #Explicitly set RTS and DTR to halt board. self.serialport.setRTS(1); @@ -231,6 +231,10 @@ 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; @@ -345,7 +349,8 @@ class GoodFET: #time.sleep(0.1) return recbuf - def picROMclock(self, masterout, slow = False): + #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) diff --git a/client/GoodFETCCSPI.py b/client/GoodFETCCSPI.py index 0e2d787..0acbdb7 100644 --- a/client/GoodFETCCSPI.py +++ b/client/GoodFETCCSPI.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # GoodFET Chipcon RF Radio Client # -# (C) 2009 Travis Goodspeed +# (C) 2009, 2012 Travis Goodspeed # # This code is being rewritten and refactored. You've been warned! @@ -20,11 +20,12 @@ class GoodFETCCSPI(GoodFET): #Set up the radio for ZigBee self.strobe(0x01); #SXOSCON self.strobe(0x02); #SCAL - self.poke(0x11, 0x0AC2); #MDMCTRL0 + self.poke(0x11, 0x0AC2 & (~0x0800)); #MDMCTRL0, promiscuous self.poke(0x12, 0x0500); #MDMCTRL1 self.poke(0x1C, 0x007F); #IOCFG0 self.poke(0x19, 0x01C4); #SECCTRL0, disabling crypto - self.RF_setsync(); + #self.poke(0x19, 0x0204); #SECCTRL0, as seen elsewhere. + #self.RF_setsync(); def ident(self): return self.peek(0x1E); #MANFIDL @@ -58,10 +59,10 @@ class GoodFETCCSPI(GoodFET): self.strobe(0x04); #0x05 for CCA def CC_RFST_RX(self): """Switch the radio to RX mode.""" - self.strobe(0x03); + self.strobe(0x03); #RX ON def CC_RFST_CAL(self): """Calibrate strobe the radio.""" - self.strobe(0x02); + self.strobe(0x02); #RX Calibrate def CC_RFST(self,state=0x00): self.strobe(state); return; @@ -133,10 +134,13 @@ class GoodFETCCSPI(GoodFET): def RF_setfreq(self,frequency): """Set the frequency in Hz.""" mhz=frequency/1000000; - fsctrl=0x8000; #self.peek(0x18)&(~0x3FF); + #fsctrl=0x8000; # + fsctrl=self.peek(0x18)&(~0x3FF); fsctrl=fsctrl+int(mhz-2048) self.poke(0x18,fsctrl); + #self.CC_RFST_IDLE(); self.strobe(0x02);#SCAL + time.sleep(0.01); self.strobe(0x03);#SRXON def RF_getfreq(self): """Get the frequency in Hz.""" @@ -162,7 +166,7 @@ class GoodFETCCSPI(GoodFET): """Set the target MAC address.""" return 0xdeadbeef; def RF_getrssi(self): - """Returns the received signal strenght, with a weird offset.""" + """Returns the received signal strength, with a weird offset.""" rssival=self.peek(0x13)&0xFF; #raw RSSI register return rssival^0x80; lastpacket=range(0,0xff); @@ -181,6 +185,8 @@ class GoodFETCCSPI(GoodFET): self.lastpacket=buffer; if(len(buffer)==0): return None; + #self.strobe(0x08); #SFLUSHRX + return buffer; def RF_txpacket(self,packet): """Send a packet through the radio.""" @@ -313,12 +319,12 @@ class GoodFETCCSPI(GoodFET): choice=choices[len]; self.poke(0x03,choice); self.maclen=len; - def printpacket(self,packet): + def printpacket(self,packet,prefix="#"): s=""; i=0; for foo in packet: s="%s %02x" % (s,ord(foo)); - print "#%s" % s; + print "%s%s" % (prefix,s); def printdissect(self,packet): try: diff --git a/client/Makefile b/client/Makefile index d0b4c5f..1787c7b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,4 +1,5 @@ - +#This is a py2exe Makefile for the Windows port, which is only +#maintained when Travis gets stuck doing MSP430 manufacturing. link: rm -f /usr/local/bin/goodfet.* /usr/local/bin/goodfet diff --git a/client/goodfet.ccspi b/client/goodfet.ccspi index fa8f2fd..f8d10bd 100755 --- a/client/goodfet.ccspi +++ b/client/goodfet.ccspi @@ -23,6 +23,10 @@ if(len(sys.argv)==1): print "%s txtest" % sys.argv[0]; print "\n%s rssi" % sys.argv[0]; + print "%s spectrum" % sys.argv[0]; + print "%s spectrumcsv" % sys.argv[0]; + + print "\n%s surf" % sys.argv[0]; print "%s sniff [chan]" % sys.argv[0]; print "%s bsniff [chan]" % sys.argv[0]; print "%s sniffdissect" % sys.argv[0]; @@ -118,11 +122,73 @@ if(sys.argv[1]=="rssi"): for foo in range(0,rssi>>2): string=("%s."%string); print "%02x %04i %s" % (rssi,rssi, string); +if(sys.argv[1]=="spectrum"): + for chan in range(2400000000,2480000000,5000000): + client.RF_setfreq(chan); + #print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6); + + client.strobe(0x02); #Calibrate + #time.sleep(0.01); + + maxrssi=0; + for foo in range(1,10): + client.CC_RFST_RX(); + rssi=client.RF_getrssi(); + maxrssi=max(rssi,maxrssi); + string=""; + for foo in range(50,rssi): + string=("%s."%string); + print "%04i %i %s" % (client.RF_getfreq()/10.0**6,rssi, string); +if(sys.argv[1]=="spectrumcsv"): + start=time.time(); + while 1: + for freq in range(2400000000,2480000000,1000000): + client.RF_setfreq(freq); + + client.strobe(0x02); #Calibrate + client.CC_RFST_RX(); + rssi=client.RF_getrssi(); + + print "%f %i %3i" % ( + time.time()-start, + client.RF_getfreq()/10.0**6, + rssi); + sys.stdout.flush(); + +if sys.argv[1]=="surf": + print "Scanning channels [11,26]."; + + #Promiscuous mode. + client.RF_promiscuity(1); + client.RF_autocrc(1); + + chan=11; + if len(sys.argv)>2: + chan=eval(sys.argv[2]); + + client.CC_RFST_RX(); + + #Now we're ready to get packets. + while 1: + if chan>26: chan=11; + + client.setup(); #Really oughtn't be necessary, but can't hurt. + client.RF_setchan(chan); + + packet=None; + lasttime=time.time(); + while packet==None and time.time()-lasttime<0.5: + packet=client.RF_rxpacket(); + if packet!=None: + client.printpacket(packet=packet, + prefix=("%02d: "%chan)); + sys.stdout.flush(); + chan=chan+1; if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"): #Promiscuous mode. client.RF_promiscuity(1); - client.RF_autocrc(0); + client.RF_autocrc(1); if len(sys.argv)>2: freq=eval(sys.argv[2]); @@ -137,6 +203,9 @@ if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"): client.RF_getfreq()/10**6); #Now we're ready to get packets. while 1: + client.setup(); #Really oughtn't be necessary, but can't hurt. + client.CC_RFST_RX(); + packet=None; while packet==None: packet=client.RF_rxpacket(); diff --git a/firmware/apps/radios/ccspi.c b/firmware/apps/radios/ccspi.c index 54b155c..6d72a69 100644 --- a/firmware/apps/radios/ccspi.c +++ b/firmware/apps/radios/ccspi.c @@ -211,10 +211,12 @@ void ccspi_handle_fn( uint8_t const app, #ifdef FIFOP //Has there been an overflow? if((!FIFO)&&FIFOP){ - //debugstr("Clearing overflow"); + debugstr("Clearing overflow"); CLRSS; ccspitrans8(0x08); //SFLUSHRX SETSS; + txdata(app,verb,0); //no packet + return; } //Is there a packet? @@ -227,19 +229,29 @@ void ccspi_handle_fn( uint8_t const app, ccspitrans8(CCSPI_RXFIFO | 0x40); //ccspitrans8(0x3F|0x40); cmddata[0]=0xff; //to be replaced with length - for(i=0;i