Added the capability to query the Special Registers for the ChipCon client.
[goodfet] / client / goodfet.ccspi
1 #!/usr/bin/env python
2
3 #GoodFET Chipcon SPI Client
4 # (C) 2011 Travis Goodspeed
5
6 #N.B.,
7 #Might be CC2420 Specific
8
9 import sys;
10 import binascii;
11 import array, time;
12
13 from GoodFETCCSPI import GoodFETCCSPI;
14
15 if(len(sys.argv)==1):
16     print "Usage: %s verb [objects]\n" % sys.argv[0];
17     print "%s info" % sys.argv[0];
18     print "%s regs" % sys.argv[0];
19     print "%s test" % sys.argv[0];
20     print "%s peek 0x$start [0x$stop]" % sys.argv[0];
21     print "%s poke 0x$adr 0x$val" % sys.argv[0];
22     print "%s txtest" % sys.argv[0];
23     
24     print "\n%s rssi" % sys.argv[0];
25     print "%s sniff [chan]" % sys.argv[0];
26     print "%s bsniff [chan]" % sys.argv[0];
27     print "%s sniffdissect" % sys.argv[0];
28     
29     
30     print;
31     print "%s txtoscount [-i|-r]   TinyOS BlinkToLED" % sys.argv[0];    
32     
33     sys.exit();
34
35 #Initialize FET and set baud rate
36 client=GoodFETCCSPI();
37 client.serInit()
38
39 client.setup();
40
41 #Dummy read.
42 #Might read as all ones if chip has a startup delay.
43
44 if(sys.argv[1]=="carrier"):
45     if len(sys.argv)>2:
46         client.RF_setfreq(eval(sys.argv[2]));
47     while 1:
48         client.RF_carrier();
49     while(1):
50         time.sleep(1);
51
52 if(sys.argv[1]=="modulated_spectrum"):
53     if len(sys.argv)>2:
54         client.RF_setfreq(eval(sys.argv[2]));
55     while 1:
56         client.RF_modulated_spectrum();
57     while(1):
58         time.sleep(1);
59
60 if(sys.argv[1]=="info"):
61     print "Found   %s" % client.identstr();
62     print "Freq:   %05f MHz" % (client.RF_getfreq()/(10**6));
63     print "Status: %s" % client.status();
64 if(sys.argv[1]=="regs"):
65     for adr in range(0x10,0x40): #*1024):
66         val=client.peek(adr);
67         print "%04x:=0x%04x" % (adr,val);
68 if(sys.argv[1]=="test"):
69     data=client.trans([0x20, 0xde, 0xad]);
70     print "%02x %02x" % (ord(data[1]), ord(data[2]));
71     data=client.trans([0x40|0x20, 0xde, 0xad]);
72     print "%02x %02x" % (ord(data[1]), ord(data[2]));
73 if(sys.argv[1]=="rssi"):
74     if len(sys.argv)>2:
75         freq=eval(sys.argv[2]);
76         if freq>100:
77             client.RF_setfreq(freq);
78         else:
79             client.RF_setchan(freq);
80     print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
81         
82     client.strobe(0x02); #Calibrate
83     time.sleep(1);
84     
85     while 1:
86         client.CC_RFST_RX();
87         #client.strobe(0x03); #SRXON
88         rssi=client.RF_getrssi();
89         #client.CC_RFST_IDLE(); #idle
90         time.sleep(0.01);
91         string="";
92         for foo in range(0,rssi>>2):
93             string=("%s."%string);
94         print "%02x %04i %s" % (rssi,rssi, string); 
95 if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
96     #Promiscuous mode.
97     client.RF_promiscuity(1);
98     client.RF_autocrc(0);
99     
100     if len(sys.argv)>2:
101         freq=eval(sys.argv[2]);
102         if freq>100:
103             client.RF_setfreq(freq);
104         else:
105             client.RF_setchan(freq);
106     client.CC_RFST_RX();
107     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
108                                             client.RF_getfreq()/10**6);
109     #Now we're ready to get packets.
110     while 1:
111         packet=None;
112         while packet==None:
113             packet=client.RF_rxpacket();
114         if sys.argv[1]=="sniffdissect":
115             client.printdissect(packet);
116         else:
117             client.printpacket(packet);
118         sys.stdout.flush();
119 if(sys.argv[1]=="bsniff"):
120     #Just broadcast.
121     client.RF_promiscuity(0);
122     client.RF_setsmac(0xFFFFFFFF);
123     client.RF_autocrc(1);
124     
125     if len(sys.argv)>2:
126         freq=eval(sys.argv[2]);
127         if freq>100:
128             client.RF_setfreq(freq);
129         else:
130             client.RF_setchan(freq);
131     client.CC_RFST_RX();
132     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
133                                             client.RF_getfreq()/10**6);
134     #Now we're ready to get packets.
135     while 1:
136         packet=None;
137         while packet==None:
138             packet=client.RF_rxpacket();
139         client.printpacket(packet);
140         sys.stdout.flush();
141
142 if(sys.argv[1]=="txtest"):
143     if len(sys.argv)>2:
144         freq=eval(sys.argv[2]);
145         if freq>100:
146             client.RF_setfreq(freq);
147         else:
148             client.RF_setchan(freq);
149     print "Transmitting DEADBEEF as %010x on %i MHz" % (
150         client.RF_getsmac(),
151         client.RF_getfreq()/10**6);
152     
153     while 1:
154         client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
155                             0xff, 0xff, 0xff, 0xff,
156                             0xde, 0xad, 0xbe, 0xef,
157                             0xba, 0xbe, 0xc0]);
158 if(sys.argv[1]=="txtoscount"):
159     '''
160     Clone of what TinyOS's RadioCountToLeds demo code does.  Specify a
161     channel a TinyOS mote programmed with RadioCountToLeds is on, and
162     this will act as the second device.
163     '''
164     if (len(sys.argv)<=3):
165         print "Provide -r to work via replays or -i to work via incrementing itself.";
166         sys.exit(1);
167     if (sys.argv[3]=="-r"):
168         client.RF_promiscuity(1);
169     client.RF_autocrc(1);
170     if len(sys.argv)>2:
171         freq=eval(sys.argv[2]);
172         if freq>100:
173             client.RF_setfreq(freq);
174         else:
175             client.RF_setchan(freq);
176     if (sys.argv[3]=="-r"):
177         client.CC_RFST_RX();
178         print "Listening as %010x on %i MHz" % (client.RF_getsmac(), client.RF_getfreq()/10**6);
179     print "Transmitting like the TinyOS CountToRadio program on %i MHz" % (client.RF_getfreq()/10**6);
180     if (sys.argv[3]=="-i"):
181         i = 0;
182         countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
183     while 1:
184         if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
185             packet=None;
186             while packet==None:
187                 packet=client.RF_rxpacket();
188             pkt = packet[:14];
189             client.RF_txpacket(pkt);
190         elif (sys.argv[3]=="-i"): #give -i to have it increment and send
191             #Use this code for it to actually do increments itself:
192             pkt = countpkt[:];
193             pkt[3] = i;
194             pkt[13] = i+1;
195             client.RF_txpacket(pkt);
196             if i >= 31: i = 0;
197             else:       i += 1;
198             time.sleep(0.5);
199
200 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
201     if len(sys.argv)>2:
202         freq=eval(sys.argv[2]);
203         if freq>100:
204             client.RF_setfreq(freq);
205         else:
206             client.RF_setchan(freq);
207     print "Transmitting on as %010x on %i MHz" % (
208         client.RF_getsmac(),
209         client.RF_getfreq()/10**6);
210     
211     client.RF_setsync(0xFFFF);
212     
213     while 1:
214         if(sys.argv[1]=="txpiptest"):
215             client.RF_txpacket([
216                     0x7f, 
217                     #Real header, must begin with SFD.
218                     0x00, 0x00, 0x00,
219                     0x00, 0xA7,
220                     
221                     #Length
222                     0x1f, 0x01, 0x08, 0x82,
223                     0xDF, 0xff, 0xff, 0xff,
224                     0xde, 0xad, 0xbe, 0xef,
225                     0xba, 0xbe, 0xc0,
226                     
227                     #Preamble
228                     0x00, 0x00, 0x00,
229                     #SFD
230                     0x00, 0xA7,  #CC2420 SFD
231                     #Packet In Packet
232                     0x0f, 0x01, 0x08, 0x82,
233                     0xff, 0xff, 0xff, 0xff,
234                     0xde, 0xad, 0xbe, 0xef,
235                     0xba, 0xbe, 0xc0,
236                     
237                     0xff, 0xff, 0xff, 0xff,
238                     0xff, 0xff, 0xff, 0xff,
239                     0xff, 0xff, 0xff, 0xff,
240                     0xff, 0xff, 0xff, 0xff,
241                     0xff, 0xff, 0xff, 0xff,
242                     0xff, 0xff, 0xff, 0xff,
243                     0xff, 0xff, 0xff, 0xff,
244                     ]);
245         elif(sys.argv[1]=="txpipscapy"):
246             try:
247                 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
248                 import struct
249             except ImportError:
250                 print "To use packet building, Scapy must be installed and have the dot15d4 extension present."
251                 print "try: hg clone http://hg.secdev.org/scapy-com";
252                 print "     sudo ./setup.py install";
253             #Overall method is to build from the inner packet outwards in the pkt string
254             # Make inner packet
255             scapyinner = Dot15d4FCS(seqnum=130)/Dot15d4Data()/Raw('\xde\xad\xbe\xef');
256             #pkt = str(scapyinner)[:-2] + '\xba\xbe\xc0';
257             pkt = str(scapyinner);                  #build inner pkt to bytes, adding FCS automatically
258             #pkt = '\x0f'+pkt
259             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length
260             pkt = "\x00\x00\x00\x00\xA7" + pkt      #add preamble and SFD to inner packet
261             # Make outer (wrapping) packet
262             scapyouter = Dot15d4(seqnum=130)/Dot15d4Data(dest_panid=0xffdf)/Raw('\xde\xad\xbe\xef\xba\xbe\xc0') #TODO why need these last 3 bytes?
263             pkt = str(scapyouter) + pkt
264             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length
265             pkt = '\x00\x00\x00\x00\xA7' + pkt + ('\xff'*28) #start with preamble/SFD and add 0xff fill at end
266             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length (originally used \x7f)
267             client.printpacket(pkt)
268             client.RF_autocrc(1);
269             client.RF_txpacket(pkt)
270
271
272 if(sys.argv[1]=="peek"):
273     start=0x0000;
274     if(len(sys.argv)>2):
275         start=int(sys.argv[2],16);
276     stop=start;
277     if(len(sys.argv)>3):
278         stop=int(sys.argv[3],16);
279     print "Peeking from %04x to %04x." % (start,stop);
280     while start<=stop:
281         print "%04x: 0x%04x" % (start,client.peek(start));
282         start=start+1;
283 if(sys.argv[1]=="poke"):
284     start=0x0000;
285     val=0x00;
286     if(len(sys.argv)>2):
287         start=int(sys.argv[2],16);
288     if(len(sys.argv)>3):
289         val=int(sys.argv[3],16);
290     print "Poking r%02x to become 0x%04x." % (start,val);
291     
292     client.poke(start,val);
293