2dfaa7eb30112220d8b16f6a42de386052afe631
[goodfet] / client / GoodFETCCSPI.py
1 #!/usr/bin/env python
2 # GoodFET Chipcon RF Radio Client
3
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
5 #
6 # This code is being rewritten and refactored.  You've been warned!
7
8 import sys, time, string, cStringIO, struct, glob, serial, os;
9
10 from GoodFET import GoodFET;
11
12 class GoodFETCCSPI(GoodFET):
13     CCSPIAPP=0x51;
14     CCversions={0x233d: "CC2420",
15                 }
16     def setup(self):
17         """Move the FET into the CCSPI application."""
18         self.writecmd(self.CCSPIAPP,0x10,0,self.data); #CCSPI/SETUP
19         
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
26         
27     def ident(self):
28         return self.peek(0x1E); #MANFIDL
29     def identstr(self):
30         manfidl=self.peek(0x1E);
31         #manfidh=self.peek(0x1f);
32         try:
33             return "%s" % (self.CCversions[manfidl]); 
34         except:
35             return "Unknown0x%04x" % manfidl;
36     def trans8(self,byte):
37         """Read and write 8 bits by CCSPI."""
38         data=self.CCSPItrans([byte]);
39         return ord(data[0]);
40     
41     def trans(self,data):
42         """Exchange data by CCSPI."""
43         self.data=data;
44         self.writecmd(self.CCSPIAPP,0x00,len(data),data);
45         return self.data;
46     def strobe(self,reg=0x00):
47         """Strobes a strobe register, returning the status."""
48         data=[reg];
49         self.trans(data);
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(0x00); #SNOP?
54     def CC_RFST_TX(self):
55         """Switch the radio to TX mode."""
56         self.strobe(0x04);  #0x05 for CCA
57     def CC_RFST_RX(self):
58         """Switch the radio to RX mode."""
59         self.strobe(0x03);
60     def CC_RFST_CAL(self):
61         """Calibrate strobe the radio."""
62         self.strobe(0x02);
63     def CC_RFST(self,state=0x00):
64         self.strobe(state);
65         return;
66     def peek(self,reg,bytes=2):
67         """Read a CCSPI Register.  For long regs, result is flipped."""
68         
69         #Reg is ORed with 0x40 by the GoodFET.
70         data=[reg,0,0];
71         
72         #Automatically calibrate the len.
73         bytes=2;
74         
75         self.writecmd(self.CCSPIAPP,0x02,len(data),data);
76         toret=(
77             ord(self.data[2])+
78             (ord(self.data[1])<<8)
79             );
80         return toret;
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." %(
87                 reg,
88                 val,
89                 self.peek(reg,bytes));
90         return;
91     
92     def status(self):
93         """Read the status byte."""
94         status=self.strobe(0x00);
95         print "Status=%02x" % status;
96     
97     #Radio stuff begins here.
98     def RF_setenc(self,code="802.15.4"):
99         """Set the encoding type."""
100         return;
101     def RF_getenc(self):
102         """Get the encoding type."""
103         return "802.15.4";
104     def RF_getrate(self):
105         return 0;
106     def RF_setrate(self,rate=0):
107         return 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)
118         return mhz*1000000;
119     def RF_getsmac(self):
120         """Return the source MAC address."""
121         return 0xdeadbeef;
122     def RF_setsmac(self,mac):
123         """Set the source MAC address."""
124         return 0xdeadbeef;
125     def RF_gettmac(self):
126         """Return the target MAC address."""
127         return 0xdeadbeef;
128     def RF_settmac(self,mac):
129         """Set the target MAC address."""
130         return 0xdeadbeef;
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
134         return rssival^0x80;
135     def RF_rxpacket(self):
136         """Get a packet from the radio.  Returns None if none is waiting."""
137         print "Don't know how to get a packet.";
138         return None;
139     def RF_carrier(self):
140         """Hold a carrier wave on the present frequency."""
141         print "Don't know how to hold a carrier.";
142     packetlen=16;
143     def RF_setpacketlen(self,len=16):
144         """Set the number of bytes in the expected payload."""
145         #self.poke(0x11,len);
146         self.packetlen=len;
147     def RF_getpacketlen(self):
148         """Set the number of bytes in the expected payload."""
149         #len=self.peek(0x11);
150         self.packetlen=len;
151         return len;
152     maclen=5;
153     def RF_getmaclen(self):
154         """Get the number of bytes in the MAC address."""
155         choices=[0, 3, 4, 5];
156         choice=self.peek(0x03)&3;
157         self.maclen=choices[choice];
158         return self.maclen;
159     def RF_setmaclen(self,len):
160         """Set the number of bytes in the MAC address."""
161         choices=["illegal", "illegal", "illegal", 
162                  1, 2, 3];
163         choice=choices[len];
164         self.poke(0x03,choice);
165         self.maclen=len;