X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETCCSPI.py;h=2e69d464f4eb07665b1068790de8105f0ec2958c;hp=48b219e29b6c1cae96da7bc9cacf74cdb792e963;hb=053fca013042a25eecdae93dc08955d6cc106468;hpb=90e7c66a3f27625e40d763b3b4ec41c767d086f9 diff --git a/client/GoodFETCCSPI.py b/client/GoodFETCCSPI.py index 48b219e..2e69d46 100644 --- a/client/GoodFETCCSPI.py +++ b/client/GoodFETCCSPI.py @@ -10,154 +10,163 @@ import sys, time, string, cStringIO, struct, glob, serial, os; from GoodFET import GoodFET; class GoodFETCCSPI(GoodFET): - CCSPIAPP=0x50; - def CCSPIsetup(self): + CCSPIAPP=0x51; + CCversions={0x233d: "CC2420", + } + def setup(self): """Move the FET into the CCSPI application.""" self.writecmd(self.CCSPIAPP,0x10,0,self.data); #CCSPI/SETUP - def CCSPItrans8(self,byte): + #Set up the radio for ZigBee + self.strobe(0x01); #SXOSCON + self.poke(0x11, 0x0AC2); #MDMCTRL0 + self.poke(0x12, 0x0500); #MDMCTRL1 + self.poke(0x1C, 0x007F); #IOCFG0 + self.poke(0x19, 0x01C4); #SECCTRL0, disabling crypto + + def ident(self): + return self.peek(0x1E); #MANFIDL + def identstr(self): + manfidl=self.peek(0x1E); + #manfidh=self.peek(0x1f); + try: + return "%s" % (self.CCversions[manfidl]); + except: + return "Unknown0x%04x" % manfidl; + def trans8(self,byte): """Read and write 8 bits by CCSPI.""" data=self.CCSPItrans([byte]); return ord(data[0]); - def CCSPItrans(self,data): + def trans(self,data): """Exchange data by CCSPI.""" self.data=data; self.writecmd(self.CCSPIAPP,0x00,len(data),data); return self.data; - - def peek(self,reg,bytes=-1): + def strobe(self,reg=0x00): + """Strobes a strobe register, returning the status.""" + data=[reg]; + self.trans(data); + return ord(self.data[0]); + def CC_RFST_IDLE(self): + """Switch the radio to idle mode, clearing overflows and errors.""" + self.strobe(0x06); #SRXOFF + def CC_RFST_TX(self): + """Switch the radio to TX mode.""" + self.strobe(0x04); #0x05 for CCA + def CC_RFST_RX(self): + """Switch the radio to RX mode.""" + self.strobe(0x03); + def CC_RFST_CAL(self): + """Calibrate strobe the radio.""" + self.strobe(0x02); + def CC_RFST(self,state=0x00): + self.strobe(state); + return; + def peek(self,reg,bytes=2): """Read a CCSPI Register. For long regs, result is flipped.""" - data=[reg,0,0,0,0,0]; + + #Reg is ORed with 0x40 by the GoodFET. + data=[reg,0,0]; #Automatically calibrate the len. - if bytes==-1: - bytes=1; - if reg==0x0a or reg==0x0b or reg==0x10: bytes=5; + bytes=2; self.writecmd(self.CCSPIAPP,0x02,len(data),data); - toret=0; - for i in range(0,bytes): - toret=toret|(ord(self.data[i+1])<<(8*i)); + toret=( + ord(self.data[2])+ + (ord(self.data[1])<<8) + ); return toret; - def poke(self,reg,val,bytes=-1): + def poke(self,reg,val,bytes=2): """Write a CCSPI Register.""" - data=[reg]; - - #Automatically calibrate the len. - if bytes==-1: - bytes=1; - if reg==0x0a or reg==0x0b or reg==0x10: bytes=5; - - for i in range(0,bytes): - data=data+[(val>>(8*i))&0xFF]; + data=[reg,(val>>8)&0xFF,val&0xFF]; self.writecmd(self.CCSPIAPP,0x03,len(data),data); - if self.peek(reg,bytes)!=val and reg!=0x07: - print "Warning, failed to set r%02x=%02x, got %02x." %(reg, - val, - self.peek(reg,bytes)); + if self.peek(reg,bytes)!=val: + print "Warning, failed to set r%02x=0x%04x, got %02x." %( + reg, + val, + self.peek(reg,bytes)); return; def status(self): """Read the status byte.""" - status=self.peek(0x07); + status=self.strobe(0x00); print "Status=%02x" % status; #Radio stuff begins here. - def RF_setenc(self,code="GFSK"): + def RF_setenc(self,code="802.15.4"): """Set the encoding type.""" - if code!=GFSK: - return "%s not supported by the CCSPI24L01. Try GFSK." return; def RF_getenc(self): """Get the encoding type.""" - return "GFSK"; + return "802.15.4"; def RF_getrate(self): - rate=self.peek(0x06)&0x28; - if rate==0x28: - rate=250*10**3; #256kbps - elif rate==0x08: - rate=2*10**6; #2Mbps - elif rate==0x00: - rate=1*10**6; #1Mbps - return rate; - def RF_setrate(self,rate=2*10**6): - r6=self.peek(0x06); #RF_SETUP register - r6=r6&(~0x28); #Clear rate fields. - if rate==2*10**6: - r6=r6|0x08; - elif rate==1*10**6: - r6=r6; - elif rate==250*10**3: - r6=r6|0x20; - print "Setting r6=%02x." % r6; - self.poke(0x06,r6); #Write new setting. + return 0; + def RF_setrate(self,rate=0): + return 0; def RF_setfreq(self,frequency): """Set the frequency in Hz.""" - - #On the CCSPI24L01+, register 0x05 is the offset in - #MHz above 2400. - - chan=frequency/1000000-2400; - self.poke(0x05,chan); + mhz=frequency/1000000; + fsctrl=self.peek(0x18)&~0x3FF; + fsctrl=fsctrl+int(mhz-2048) + self.poke(0x18,fsctrl); def RF_getfreq(self): """Get the frequency in Hz.""" - - #On the CCSPI24L01+, register 0x05 is the offset in - #MHz above 2400. - - return (2400+self.peek(0x05))*10**6 - self.poke(0x05,chan); + fsctrl=self.peek(0x18); + mhz=2048+(fsctrl&0x3ff) + return mhz*1000000; def RF_getsmac(self): """Return the source MAC address.""" - - #Register 0A is RX_ADDR_P0, five bytes. - mac=self.peek(0x0A, 5); - return mac; + return 0xdeadbeef; def RF_setsmac(self,mac): """Set the source MAC address.""" - - #Register 0A is RX_ADDR_P0, five bytes. - self.poke(0x0A, mac, 5); - return mac; + return 0xdeadbeef; def RF_gettmac(self): """Return the target MAC address.""" - - #Register 0x10 is TX_ADDR, five bytes. - mac=self.peek(0x10, 5); - return mac; + return 0xdeadbeef; def RF_settmac(self,mac): """Set the target MAC address.""" - - #Register 0x10 is TX_ADDR, five bytes. - self.poke(0x10, mac, 5); - return mac; - + return 0xdeadbeef; + def RF_getrssi(self): + """Returns the received signal strenght, with a weird offset.""" + rssival=self.peek(0x13)&0xFF; #raw RSSI register, should normalize this + return rssival^0x80; + lastpacket=range(0,0xff); def RF_rxpacket(self): - """Get a packet from the radio. Returns None if none is waiting.""" - if self.peek(0x07) & 0x40: - #Packet has arrived. - self.writecmd(self.CCSPIAPP,0x80,0,None); #RX Packet - data=self.data; - self.poke(0x07,0x40);#clear bit. - return data; - elif self.peek(0x07)==0: - self.writecmd(self.CCSPIAPP,0x82,0,None); #Flush - self.poke(0x07,0x40);#clear bit. - return None; + """Get a packet from the radio. Returns None if none is waiting. In + order to not require the SFD, FIFO, or FIFOP lines, this + implementation works by comparing the buffer to the older + contents. + """ + self.strobe(0x03); #SRXON + self.strobe(0x08); #SFLUSHRX + + buffer=range(0,0xff); + buffer[0]=0x3F | 0x40; #RXFIFO + buffer=self.trans(buffer); + + new=False; + for foo in range(2,20): + if buffer[foo]!=self.lastpacket[foo]: + new=True; + if not new: + return None; + + + self.lastpacket=buffer; + return buffer; def RF_carrier(self): """Hold a carrier wave on the present frequency.""" - # Set CONT_WAVE, PLL_LOCK, and 0dBm in RF_SETUP - self.poke(0x06,8+10+4+2); - + print "Don't know how to hold a carrier."; packetlen=16; def RF_setpacketlen(self,len=16): """Set the number of bytes in the expected payload.""" - self.poke(0x11,len); + #self.poke(0x11,len); self.packetlen=len; def RF_getpacketlen(self): """Set the number of bytes in the expected payload.""" - len=self.peek(0x11); + #len=self.peek(0x11); self.packetlen=len; return len; maclen=5;