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):
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);
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;
#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)
#!/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!
#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
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;
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."""
"""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);
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."""
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:
-
+#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
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];
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]);
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();
#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?
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);