2 # GoodFET Chipcon RF Radio Client
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
6 # This code is being rewritten and refactored. You've been warned!
8 import sys, time, string, cStringIO, struct, glob, serial, os;
10 from GoodFET import GoodFET;
12 class GoodFETCCSPI(GoodFET):
14 CCversions={0x233d: "CC2420",
17 """Move the FET into the CCSPI application."""
18 self.writecmd(self.CCSPIAPP,0x10,0,self.data); #CCSPI/SETUP
20 #Set up the radio for ZigBee
21 self.strobe(0x01); #SXOSCON
22 self.poke(0x11, 0x0AC2); #MDMCTRL0
23 self.poke(0x12, 0x0500); #MDMCTRL1
24 self.poke(0x1C, 0x007F); #IOCFG0
25 self.poke(0x19, 0x01C4); #SECCTRL0, disabling crypto
28 return self.peek(0x1E); #MANFIDL
30 manfidl=self.peek(0x1E);
31 #manfidh=self.peek(0x1f);
33 return "%s" % (self.CCversions[manfidl]);
35 return "Unknown0x%04x" % manfidl;
36 def trans8(self,byte):
37 """Read and write 8 bits by CCSPI."""
38 data=self.CCSPItrans([byte]);
42 """Exchange data by CCSPI."""
44 self.writecmd(self.CCSPIAPP,0x00,len(data),data);
46 def strobe(self,reg=0x00):
47 """Strobes a strobe register, returning the status."""
50 return ord(self.data[0]);
51 def CC_RFST_IDLE(self):
52 """Switch the radio to idle mode, clearing overflows and errors."""
53 self.strobe(0x06); #SRXOFF
55 """Switch the radio to TX mode."""
56 self.strobe(0x04); #0x05 for CCA
58 """Switch the radio to RX mode."""
60 def CC_RFST_CAL(self):
61 """Calibrate strobe the radio."""
63 def CC_RFST(self,state=0x00):
66 def peek(self,reg,bytes=2):
67 """Read a CCSPI Register. For long regs, result is flipped."""
69 #Reg is ORed with 0x40 by the GoodFET.
72 #Automatically calibrate the len.
75 self.writecmd(self.CCSPIAPP,0x02,len(data),data);
78 (ord(self.data[1])<<8)
81 def poke(self,reg,val,bytes=2):
82 """Write a CCSPI Register."""
83 data=[reg,(val>>8)&0xFF,val&0xFF];
84 self.writecmd(self.CCSPIAPP,0x03,len(data),data);
85 if self.peek(reg,bytes)!=val:
86 print "Warning, failed to set r%02x=0x%04x, got %02x." %(
89 self.peek(reg,bytes));
93 """Read the status byte."""
94 status=self.strobe(0x00);
95 print "Status=%02x" % status;
97 #Radio stuff begins here.
98 def RF_setenc(self,code="802.15.4"):
99 """Set the encoding type."""
102 """Get the encoding type."""
104 def RF_getrate(self):
106 def RF_setrate(self,rate=0):
108 def RF_setfreq(self,frequency):
109 """Set the frequency in Hz."""
110 mhz=frequency/1000000;
111 fsctrl=self.peek(0x18)&~0x3FF;
112 fsctrl=fsctrl+int(mhz-2048)
113 self.poke(0x18,fsctrl);
114 def RF_getfreq(self):
115 """Get the frequency in Hz."""
116 fsctrl=self.peek(0x18);
117 mhz=2048+(fsctrl&0x3ff)
119 def RF_getsmac(self):
120 """Return the source MAC address."""
122 def RF_setsmac(self,mac):
123 """Set the source MAC address."""
125 def RF_gettmac(self):
126 """Return the target MAC address."""
128 def RF_settmac(self,mac):
129 """Set the target MAC address."""
131 def RF_getrssi(self):
132 """Returns the received signal strenght, with a weird offset."""
133 rssival=self.peek(0x13)&0xFF; #raw RSSI register, should normalize this
135 lastpacket=range(0,0xff);
136 def RF_rxpacket(self):
137 """Get a packet from the radio. Returns None if none is waiting. In
138 order to not require the SFD, FIFO, or FIFOP lines, this
139 implementation works by comparing the buffer to the older
142 self.strobe(0x03); #SRXON
143 self.strobe(0x08); #SFLUSHRX
145 buffer=range(0,0xff);
146 buffer[0]=0x3F | 0x40; #RXFIFO
147 buffer=self.trans(buffer);
150 for foo in range(2,20):
151 if buffer[foo]!=self.lastpacket[foo]:
157 self.lastpacket=buffer;
159 def RF_carrier(self):
160 """Hold a carrier wave on the present frequency."""
161 print "Don't know how to hold a carrier.";
163 def RF_setpacketlen(self,len=16):
164 """Set the number of bytes in the expected payload."""
165 #self.poke(0x11,len);
167 def RF_getpacketlen(self):
168 """Set the number of bytes in the expected payload."""
169 #len=self.peek(0x11);
173 def RF_getmaclen(self):
174 """Get the number of bytes in the MAC address."""
175 choices=[0, 3, 4, 5];
176 choice=self.peek(0x03)&3;
177 self.maclen=choices[choice];
179 def RF_setmaclen(self,len):
180 """Set the number of bytes in the MAC address."""
181 choices=["illegal", "illegal", "illegal",
184 self.poke(0x03,choice);