a7dc51a474f6c33febf8f7f674b7f7b7a5d0f28a
[goodfet] / client / goodfet.nrf
1 #!/usr/bin/env python
2
3 #GoodFET SPI Flash Client
4 #by Travis Goodspeed
5
6 import sys;
7 import binascii;
8 import array;
9 import time;
10
11 from GoodFETNRF import GoodFETNRF;
12 from intelhex import IntelHex;
13
14
15 regnames=["CONFIG","EN_AA","EN_RXADDR","SETUP_AW","SETUP_RET",
16           "RF_CH","RF_SETUP","STATUS","OBSERVE_TX","RPD",
17           "RX_ADDR_P0","RX_ADDR_P1","RX_ADDR_P2","RX_ADDR_P3","RX_ADDR_P4","RX_ADDR_P5",
18           "TX_ADDR",
19           "RX_PW_P0","RX_PW_P1","RX_PW_P2","RX_PW_P3","RX_PW_P4","RX_PW_P5",
20           "FIFO_STATUS","?",
21           "?","?","?","DYNPD","FEATURE","AGC_CONFIG","?","?",
22           "?","?","?","?","?","?","?","?"];
23
24 def printpacket(packet):
25     s="";
26     i=0;
27     for foo in packet:
28         i=i+1;
29         if i>client.packetlen: break;
30         s="%s %02x" % (s,ord(foo));
31     print "%s" %s;
32
33 def printconfig():
34     print "Encoding %s" % client.RF_getenc();
35     print "Freq    %10i MHz" % (client.RF_getfreq()/10**6);
36     print "Rate    %10i kbps" % (client.RF_getrate()/1000);
37     print "PacketLen %02i bytes" % client.RF_getpacketlen();
38     #print "MacLen    %2i bytes" % client.RF_getmaclen();
39     print "SMAC  0x%010x" % client.RF_getsmac();
40     print "TMAC  0x%010x" % client.RF_gettmac();
41
42
43 if(len(sys.argv)==1):
44     print "Usage: %s verb [objects]\n" % sys.argv[0];
45     print "%s info" % sys.argv[0];
46     print "%s test" % sys.argv[0];
47     print "%s regs" % sys.argv[0];
48     print "%s pyregs" % sys.argv[0];
49
50     print "%s sniff\n\tSniffs packets by current config." % sys.argv[0];
51     print "%s sniffob\n\tSniffs OpenBeacon traffic." % sys.argv[0];
52     print "%s snifftp\n\tSniffs Turning Point Clicker traffic." % sys.argv[0];
53     print "%s snifftp\n\tSniffs SparkFun Dongle traffic." % sys.argv[0];
54     
55     print "%s hosttp\n\tHosts Turning Point Clicker traffic." % sys.argv[0];
56
57     print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
58     sys.exit();
59
60 #Initialize FET and set baud rate
61 client=GoodFETNRF();
62 client.serInit()
63
64 client.NRFsetup();
65
66 if(sys.argv[1]=="info"):
67     printconfig();
68
69 if(sys.argv[1]=="test"):
70     print "Old registers:"
71     printconfig();
72     
73     # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
74     client.poke(0x00,2);
75     #Delay of 1.5ms by round-trip.
76     
77     print "\n\n";
78     
79     #Try all data rates
80     for foo in [250*10**3,
81                 1*10**6,
82                 2*10**6]:
83         client.RF_setrate(foo);
84         if(client.RF_getrate()!=foo):
85             print "ERROR Rate %i not supported.  Got %i instead." % (foo,
86                                                                      client.RF_getrate());
87     
88     print "\n\n";
89     client.poke(0x0A,0xDEADBEEF,5);
90     #print "SMAC set to %010x" % client.RF_getsmac();
91     if client.RF_getsmac()!=0xdeadbeef:
92         print "ERROR: Failed to set MAC address.";
93     print "Final registers:"
94     printconfig();
95     
96 if(sys.argv[1]=="carrier"):
97     if len(sys.argv)>2:
98         client.RF_setfreq(eval(sys.argv[2]));
99     client.RF_carrier();
100     printconfig();
101     print "\nHolding a carrier wave.";
102     while(1):
103         time.sleep(1);
104 if(sys.argv[1]=="regs"):
105     for r in range(0,0x20):
106         print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
107 if(sys.argv[1]=="pyregs"):
108     for r in range(0,0x20):
109         print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
110
111 if(sys.argv[1]=="peek"):
112     start=0x0000;
113     if(len(sys.argv)>2):
114         start=int(sys.argv[2],16);
115     stop=start;
116     if(len(sys.argv)>3):
117         stop=int(sys.argv[3],16);
118     print "Peeking from %02x to %02x." % (start,stop);
119     while start<=stop:
120         print "%02x: %010x" % (start,client.peek(start));
121         start=start+1;
122 if(sys.argv[1]=="poke"):
123     start=0x0000;
124     val=0x00;
125     if(len(sys.argv)>2):
126         start=int(sys.argv[2],16);
127     if(len(sys.argv)>3):
128         val=int(sys.argv[3],16);
129     print "Poking %02x to become %010x." % (start,val);
130     
131     client.poke(start,val);
132     print "Poked to %04x" % client.peek(start);
133
134 if(sys.argv[1]=="sniffob"):
135     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
136     #TODO remove all poke() calls.
137     
138     client.poke(0x00,0x00); #Stop nRF
139     client.poke(0x01,0x00); #Disable Shockburst
140     client.poke(0x02,0x01); #Set RX Pipe 0
141     
142     client.RF_setfreq(2481 * 10**6);
143     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
144     client.poke(0x07,0x78); #Reset status register
145     
146     #OpenBeacon defines these in little endian as follows.
147     client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
148     #0x01, 0x02, 0x03, 0x02, 0x01
149     client.RF_setsmac(0x0102030201);
150     #'O', 'C', 'A', 'E', 'B'
151     client.RF_settmac(0x424541434F);
152     
153     #Set packet length of 16.
154     client.RF_setpacketlen(16);
155     
156     #Power radio, prime for RX, one-byte checksum.
157     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
158     
159     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
160                                            client.RF_getfreq()/10**6);
161     #Now we're ready to get packets.
162     while 1:
163         packet=None;
164         while packet==None:
165             #time.sleep(0.1);
166             packet=client.RF_rxpacket();
167         printpacket(packet);
168         sys.stdout.flush();
169
170 if(sys.argv[1]=="regbits"):
171     print "Scanning registers to determine which bits are valid."
172     regbits=range(0,0x30);
173     for r in range(0,0x30):
174         old=client.peek(r);
175         #Which bits can be set?
176         client.poke(r,0xFF);
177         ones=client.peek(r);
178         #Which bits can be clear?
179         client.poke(r,0x00);
180         zeroes=client.peek(r);
181         regbits[r]=(ones & (~zeroes));
182     for r in range(0,0x30):
183         if regbits[r]!=0:
184             print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
185 if(sys.argv[1]=="sniffprom"):
186     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
187     #TODO remove all poke() calls.
188     
189     client.poke(0x00,0x00); #Stop nRF
190     client.poke(0x01,0x00); #Disable Shockburst
191     client.poke(0x02,0x01); #Set RX Pipe 0
192     
193     client.RF_setfreq(2481 * 10**6);
194     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
195     client.poke(0x07,0x78); #Reset status register
196     
197     #OpenBeacon defines these in little endian as follows.
198     client.RF_setmaclen(5); # SETUP_AW for 3-byte addresses.
199     #0x01, 0x02, 0x03, 0x02, 0x01
200     client.RF_setsmac(0x0102030201);
201     #'O', 'C', 'A', 'E', 'B'
202     client.RF_settmac(0x424541434F);
203     
204     #Mac packet length, illegally 0-length address field.
205     client.RF_setpacketlen(32);
206     client.poke(0x03,0);
207     
208     #Power radio, prime for RX, one-byte checksum.
209     client.poke(0x00,0x70|0x03); #0x08 for one byte, 0x04 for two.
210     
211     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
212                                            client.RF_getfreq()/10**6);
213     #Now we're ready to get packets.
214     while 1:
215         packet=None;
216         while packet==None:
217             #time.sleep(0.1);
218             packet=client.RF_rxpacket();
219         printpacket(packet);
220         sys.stdout.flush();
221
222 if(sys.argv[1]=="sniffsf"):
223     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
224     #TODO remove all poke() calls.
225     
226     client.poke(0x00,0x00); #Stop nRF
227     client.poke(0x01,0x00); #Disable Shockburst
228     client.poke(0x02,0x01); #Set RX Pipe 0
229     
230     client.RF_setfreq(2402 * 10**6);
231     client.poke(0x06,0x07); #1Mbps
232     client.poke(0x07,0x78); #Reset status register
233     
234     #OpenBeacon defines these in little endian as follows.
235     client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
236     #0x01, 0x02, 0x03, 0x02, 0x01
237     client.RF_setsmac(0xe7e7e7e7e7);
238     #'O', 'C', 'A', 'E', 'B'
239     client.RF_settmac(0xe7e7e7e7e7);
240     
241     #Set packet length of 16.
242     client.RF_setpacketlen(4);
243     
244     #Power radio, prime for RX, one-byte checksum.
245     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
246     
247     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
248                                            client.RF_getfreq()/10**6);
249     #Now we're ready to get packets.
250     while 1:
251         packet=None;
252         while packet==None:
253             #time.sleep(0.1);
254             packet=client.RF_rxpacket();
255         printpacket(packet);
256         sys.stdout.flush();
257
258 if(sys.argv[1]=="snifftp"):
259     client.poke(0x00,0x00); #Stop nRF
260     client.poke(0x01,0x00); #Disable Shockburst
261     client.poke(0x02,0x01); #Set RX Pipe 0
262     
263     client.RF_setfreq((2400+0x29) * 10**6);
264     client.poke(0x06,0x00); #1Mbps
265     client.poke(0x07,0x78); #Reset status register
266     
267     client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
268     client.RF_setsmac(0x123456);
269     client.RF_setpacketlen(4);
270     
271     #Power radio, prime for RX, two-byte checksum.
272     client.poke(0x00,0x70|0x03|0x04|0x08);
273     
274     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
275                                            client.RF_getfreq()/10**6);
276     #Now we're ready to get packets.
277     while 1:
278         packet=None;
279         while packet==None:
280             #time.sleep(0.1);
281             packet=client.RF_rxpacket();
282         printpacket(packet);
283         sys.stdout.flush();
284
285 if(sys.argv[1]=="hosttp"):
286     client.poke(0x00,0x00); #Stop nRF
287     client.poke(0x01,0x00); #Disable Shockburst
288     client.poke(0x02,0x01); #Set RX Pipe 0
289     
290     chan=0x29;
291
292     client.RF_setfreq((2400+chan) * 10**6);
293     client.poke(0x06,0x00); #1Mbps
294     client.poke(0x07,0x78); #Reset status register
295     
296     client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
297     client.RF_setsmac(0x123456);
298     client.RF_setpacketlen(4);
299     
300     #Power radio, prime for RX, two-byte checksum.
301     client.poke(0x00,0x70|0x03|0x04|0x08);
302     
303     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
304                                            client.RF_getfreq()/10**6);
305     #Now we're ready to get packets.
306     while 1:
307         packet=None;
308         while packet==None:
309             packet=client.RF_rxpacket();
310         mac=((ord(packet[0])<<16)+
311              (ord(packet[1])<<8)+
312              ord(packet[2]));
313         key=packet[3];
314         print "%c from %06x" % (key,mac);
315         sys.stdout.flush();
316
317 if(sys.argv[1]=="sniff"):
318     #client.poke(0x00,0x00); #Stop nRF
319     client.poke(0x07,0x78); #Reset status register
320     
321     #Power radio, prime for RX, checksum.
322     client.poke(0x00,0x70|0x03|0x08);
323     
324     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
325                                            client.RF_getfreq()/10**6);
326     #Now we're ready to get packets.
327     
328     while 1:
329         packet=None;
330         while packet==None:
331             #time.sleep(0.1);
332             packet=client.RF_rxpacket();
333         printpacket(packet);
334         sys.stdout.flush();
335 if(sys.argv[1]=="explore"):
336     #client.poke(0x00,0x00); #Stop nRF
337     client.poke(0x07,0x78); #Reset status register
338     
339     #Power radio, prime for RX, no checksum.
340     client.poke(0x00,0x70|0x03);
341     
342     #Set packet length of 32.
343     #Without checksums, extra data will mix in.
344     client.RF_setpacketlen(32);
345     client.RF_setmaclen(3); # shortest address length
346     
347     #Now we're ready to get packets.
348     for smac in [0x0102030201, 0]:
349         client.RF_setsmac(smac);
350         for chan in range(0,0x80):
351             client.RF_setfreq((2400+chan) * 10**6);
352             time.sleep(1);
353             packet=client.RF_rxpacket();
354             if packet!=None:
355                 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
356                                                         client.RF_getfreq()/10**6);
357                 printpacket(packet);
358                 sys.stdout.flush();