Lots of new CC2420 stabilization.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 14 Aug 2012 20:29:57 +0000 (20:29 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 14 Aug 2012 20:29:57 +0000 (20:29 +0000)
'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
client/GoodFETCCSPI.py
client/Makefile
client/goodfet.ccspi
firmware/apps/radios/ccspi.c

index 23a147f..05c2045 100755 (executable)
@@ -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)
index 0e2d787..0acbdb7 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # GoodFET Chipcon RF Radio Client
 # 
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+# (C) 2009, 2012 Travis Goodspeed <travis at radiantmachines.com>
 #
 # 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:
index d0b4c5f..1787c7b 100644 (file)
@@ -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
index fa8f2fd..f8d10bd 100755 (executable)
@@ -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();
index 54b155c..6d72a69 100644 (file)
@@ -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<cmddata[0]+2;i++)
-        cmddata[i]=ccspitrans8(0xde);
+      
+      
+      /* This reads too far on some CC2420 revisions, but on others it
+        works fine.  It probably has to do with whether FIFO drops
+        before or after the SPI clocking.
+        
+        A software fix is to reset the CC2420 between packets.  This
+        works, but a better solution is desired.
+      */
+      //for(i=0;i<cmddata[0]+1;i++)
+      for(i=0;FIFO && i<0x80;i++)
+        cmddata[i]=ccspitrans8(0x00);
       SETSS;
 
-      //Flush buffer.
+      /* We used to flush the RX buffer after receive. No longer.
       CLRSS;
       ccspitrans8(0x08); //SFLUSHRX
       SETSS;
-      
+      */
       
       //Only should transmit length of one more than the reported
       // length of the frame, which holds the length byte:
-      txdata(app,verb,cmddata[0]+1);
+      txdata(app,verb,i&0x7F);
     }else{
       //No packet.
       txdata(app,verb,0);