1
2
3
4
5
6
7
8 import sys, time, string, cStringIO, struct, glob, os;
9 import sqlite3;
10
11 fmt = ("B", "<H", None, "<L")
12
14 import GoodFET, GoodFETCC, GoodFETAVR, GoodFETSPI, GoodFETMSP430, GoodFETNRF, GoodFETCCSPI;
15 if(name=="GoodFET" or name=="monitor"): return GoodFET.GoodFET();
16 elif name=="cc" or name=="cc51": return GoodFETCC.GoodFETCC();
17 elif name=="cc2420" or name=="ccspi": return GoodFETCCSPI.GoodFETCCSPI();
18 elif name=="avr": return GoodFETAVR.GoodFETAVR();
19 elif name=="spi": return GoodFETSPI.GoodFETSPI();
20 elif name=="msp430": return GoodFETMSP430.GoodFETMSP430();
21 elif name=="nrf": return GoodFETNRF.GoodFETNRF();
22
23 print "Unsupported target: %s" % name;
24 sys.exit(0);
25
27 """GoodFET Symbol Table"""
28 db=sqlite3.connect(":memory:");
29
31 self.db.execute("create table if not exists symbols(adr,name,memory,size,comment);");
33 self.db.commit();
34 c=self.db.cursor();
35 try:
36 c.execute("select adr,memory from symbols where name=?",(name,));
37 for row in c:
38
39 sys.stdout.flush();
40 return row[0];
41
42 except:
43
44 return eval(name);
45 return eval(name);
46 - def define(self,adr,name,comment="",memory="vn",size=16):
47 self.db.execute("insert into symbols(adr,name,memory,size,comment)"
48 "values(?,?,?,?,?);", (
49 adr,name,memory,size,comment));
50
52 """py-bluez class for emulating py-serial."""
54 import bluetooth;
55 if btaddr==None or btaddr=="none" or btaddr=="bluetooth":
56 print "performing inquiry..."
57 nearby_devices = bluetooth.discover_devices(lookup_names = True)
58 print "found %d devices" % len(nearby_devices)
59 for addr, name in nearby_devices:
60 print " %s - '%s'" % (addr, name)
61
62 if name=='FireFly-A6BD':
63 btaddr=addr;
64 if name=='RN42-A94A':
65 btaddr=addr;
66
67 print "Please set $GOODFET to the address of your device.";
68 sys.exit();
69 print "Identified GoodFET at %s" % btaddr;
70
71
72 port=1;
73
74 print "Connecting to %s on port %i." % (btaddr, port);
75 sock=bluetooth.BluetoothSocket(bluetooth.RFCOMM);
76 self.sock=sock;
77 sock.connect((btaddr,port));
78 sock.settimeout(10);
79
80
81
82
83
84
85
86
87 return;
88
90 """Send traffic."""
91 import time;
92 self.sock.send(msg);
93
94 return;
95 - def read(self,length):
96 """Read traffic."""
97 data="";
98 while len(data)<length:
99 data=data+self.sock.recv(length-len(data));
100 return data;
101
103 """GoodFET Client Library"""
104
105 besilent=0;
106 app=0;
107 verb=0;
108 count=0;
109 data="";
110 verbose=False
111
112 GLITCHAPP=0x71;
113 MONITORAPP=0x00;
114 symbols=SymbolTable();
115
119 from GoodFETConsole import GoodFETConsole;
120 return GoodFETConsole(self);
125 - def serInit(self, port=None, timeout=2, attemptlimit=None):
126 """Open a serial port of some kind."""
127 import re;
128
129 if port==None:
130 port=os.environ.get("GOODFET");
131 if port=="bluetooth" or (port is not None and re.match("..:..:..:..:..:..",port)):
132 self.btInit(port,2,attemptlimit);
133 else:
134 self.pyserInit(port,timeout,attemptlimit);
135 - def btInit(self, port, timeout, attemptlimit):
136 """Open a bluetooth port.""";
137
138 self.serialport=GoodFETbtser(port);
139
140 - def pyserInit(self, port, timeout, attemptlimit):
141 """Open the serial port"""
142
143 import serial;
144 fixserial=False;
145
146 if os.name=='nt' and sys.version.find('64 bit')!=-1:
147 print "WARNING: PySerial requires a 32-bit Python build in Windows.";
148
149 if port is None and os.environ.get("GOODFET")!=None:
150 glob_list = glob.glob(os.environ.get("GOODFET"));
151 if len(glob_list) > 0:
152 port = glob_list[0];
153 else:
154 port = os.environ.get("GOODFET");
155 if port is None:
156 glob_list = glob.glob("/dev/tty.usbserial*");
157 if len(glob_list) > 0:
158 port = glob_list[0];
159 if port is None:
160 glob_list = glob.glob("/dev/ttyUSB*");
161 if len(glob_list) > 0:
162 port = glob_list[0];
163 if port is None:
164 glob_list = glob.glob("/dev/ttyU0");
165 if len(glob_list) > 0:
166 port = glob_list[0];
167 if port is None and os.name=='nt':
168 from scanwin32 import winScan;
169 scan=winScan();
170 for order,comport,desc,hwid in sorted(scan.comports()):
171 try:
172 if hwid.index('FTDI')==0:
173 port=comport;
174
175 except:
176
177 a=1;
178
179 baud=115200;
180 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'):
181 baud=19200;
182 self.serialport = serial.Serial(
183 port,
184
185 baud,
186 parity = serial.PARITY_NONE,
187 timeout=timeout
188 )
189
190 self.verb=0;
191 attempts=0;
192 connected=0;
193 while connected==0:
194 while self.verb!=0x7F or self.data!="http://goodfet.sf.net/":
195
196
197 if attemptlimit is not None and attempts >= attemptlimit:
198 return
199 elif attempts==2 and os.environ.get("board")!='telosb':
200 print "See the GoodFET FAQ about missing info flash.";
201 self.serialport.setTimeout(0.2);
202 elif attempts == 100:
203 print "Tried 100 times to connect and failed."
204 sys.stdout.write("Continuing to try forever.")
205 sys.stdout.flush()
206 self.verbose=True
207 elif attempts > 100 and attempts % 10 == 0:
208 sys.stdout.write('.')
209 sys.stdout.flush()
210
211
212
213
214 if (os.environ.get("board")=='telosb'):
215
216 self.telosBReset();
217 elif (os.environ.get("board")=='z1'):
218 self.bslResetZ1(invokeBSL=0);
219 elif (os.environ.get("board")=='apimote1') or (os.environ.get("board")=='apimote'):
220
221
222 self.serialport.setRTS(1);
223 self.serialport.setDTR(1);
224
225 self.serialport.setRTS(0);
226 else:
227
228 self.serialport.setRTS(1);
229 self.serialport.setDTR(1);
230
231 self.serialport.setDTR(0);
232
233
234
235
236
237
238
239
240
241
242 attempts=attempts+1;
243 self.readcmd();
244
245 if self.verb!=0x7f:
246
247 self.readcmd();
248
249
250
251 connected=1;
252 if attempts >= 100:
253 print ""
254 olds=self.infostring();
255 clocking=self.monitorclocking();
256 for foo in range(1,30):
257 if not self.monitorecho():
258 if self.verbose:
259 print "Comm error on %i try, resyncing out of %s." % (foo,
260 clocking);
261 connected=0;
262 break;
263 if self.verbose: print "Connected after %02i attempts." % attempts;
264 self.mon_connected();
265 self.serialport.setTimeout(12);
267 self.serialport.close();
268
270 '''Helper function for support of the TelosB platform.'''
271 self.serialport.setRTS(not level)
273 '''Helper function for support of the TelosB platform.'''
274 self.serialport.setDTR(not level)
310
312 '''
313 Helper function for support of the Z1 mote platform.
314 Applies BSL entry sequence on RST/NMI and TEST/VPP pins.
315 By now only BSL mode is accessed.
316 @type invokeBSL: Integer
317 @param invokeBSL: 1 for a complete sequence, or 0 to only access RST/NMI pin
318 '''
319
320 if invokeBSL:
321
322 time.sleep(0.1)
323 self.writepicROM(0xFF, 0xFF)
324 time.sleep(0.1)
325
326 else:
327
328 time.sleep(0.1)
329 self.writepicROM(0xFF, 0xFE)
330 time.sleep(0.1)
331
332
334 ''' Writes data to @address'''
335 for i in range(7,-1,-1):
336 self.picROMclock((address >> i) & 0x01)
337 self.picROMclock(0)
338 recbuf = 0
339 for i in range(7,-1,-1):
340 s = ((data >> i) & 0x01)
341
342 if i < 1:
343 r = not self.picROMclock(s, True)
344 else:
345 r = not self.picROMclock(s)
346 recbuf = (recbuf << 1) + r
347
348 self.picROMclock(0, True)
349
350
351
352
353 return recbuf
355 ''' reads a byte from @address'''
356 for i in range(7,-1,-1):
357 self.picROMclock((address >> i) & 0x01)
358 self.picROMclock(1)
359 recbuf = 0
360 r = 0
361 for i in range(7,-1,-1):
362 r = self.picROMclock(0)
363 recbuf = (recbuf << 1) + r
364 self.picROMclock(r)
365
366 return recbuf
367
368
370
371 self.serialport.setRTS(masterout)
372 self.serialport.setDTR(1)
373
374 self.serialport.setDTR(0)
375 if slow:
376 time.sleep(0.02)
377 return self.serialport.getCTS()
378
380
381 self.serialport.setRTS(masterout)
382 self.serialport.setDTR(1)
383 self.serialport.setDTR(0)
384 time.sleep(0.02)
385 return self.serialport.getCTS()
386
415
417 writecmd(0,0xC2,[size&0xFF,(size>>16)&0xFF]);
418 print "Got %02x%02x buffer size." % (self.data[1],self.data[0]);
419
420 - def writecmd(self, app, verb, count=0, data=[]):
421 """Write a command and some data to the GoodFET."""
422 self.serialport.write(chr(app));
423 self.serialport.write(chr(verb));
424
425
426
427
428
429
430
431 self.serialport.write(chr(count&0xFF));
432 self.serialport.write(chr(count>>8));
433
434 if self.verbose:
435 print "Tx: ( 0x%02x, 0x%02x, 0x%04x )" % ( app, verb, count )
436
437
438
439 if count!=0:
440 if(isinstance(data,list)):
441 for i in range(0,count):
442
443 data[i]=chr(data[i]);
444
445 outstr=''.join(data);
446 self.serialport.write(outstr);
447 if not self.besilent:
448 return self.readcmd()
449 else:
450 return []
451
453 """Read a reply from the GoodFET."""
454 while 1:
455 try:
456
457 self.app=ord(self.serialport.read(1));
458
459 self.verb=ord(self.serialport.read(1));
460
461
462 if self.app==0x00:
463 while self.verb==0x00:
464 self.verb=ord(self.serialport.read(1));
465
466
467 self.count=(
468 ord(self.serialport.read(1))
469 +(ord(self.serialport.read(1))<<8)
470 );
471
472 if self.verbose:
473 print "Rx: ( 0x%02x, 0x%02x, 0x%04x )" % ( self.app, self.verb, self.count )
474
475
476 if self.app==0xFF:
477 if self.verb==0xFF:
478 print "# DEBUG %s" % self.serialport.read(self.count)
479 elif self.verb==0xFE:
480 print "# DEBUG 0x%x" % struct.unpack(fmt[self.count-1], self.serialport.read(self.count))[0]
481 elif self.verb==0xFD:
482
483 print "# NOP.";
484
485 sys.stdout.flush();
486 else:
487 self.data=self.serialport.read(self.count);
488 return self.data;
489 except TypeError:
490 if self.connected:
491 print "Warning: waiting for serial read timed out (most likely).";
492
493
494 return self.data;
495
496
501
507
509 """Glitch into the AVR application."""
510 self.glitchVerb(self.APP,0x20,None);
512 """Measure the timer of the START verb."""
513 return self.glitchTime(self.APP,0x20,None);
515 """Time the execution of a verb."""
516 if data==None: data=[];
517 self.data=[app&0xff, verb&0xFF]+data;
518 print "Timing app %02x verb %02x." % (app,verb);
519 self.writecmd(self.GLITCHAPP,0x82,len(self.data),self.data);
520 time=ord(self.data[0])+(ord(self.data[1])<<8);
521 print "Timed to be %i." % time;
522 return time;
524 """Set glitching voltages. (0x0fff is max.)"""
525 self.data=[low&0xff, (low>>8)&0xff,
526 high&0xff, (high>>8)&0xff];
527 self.writecmd(self.GLITCHAPP,0x90,4,self.data);
528
534
535
536
538 """Transmissions halted when 1."""
539 self.besilent=s;
540 print "besilent is %i" % self.besilent;
541 self.writecmd(0,0xB0,1,[s]);
542 connected=0;
544 """Announce to the monitor that the connection is good."""
545 self.connected=1;
546 self.writecmd(0,0xB1,0,[]);
547 - def out(self,byte):
548 """Write a byte to P5OUT."""
549 self.writecmd(0,0xA1,1,[byte]);
550 - def dir(self,byte):
551 """Write a byte to P5DIR."""
552 self.writecmd(0,0xA0,1,[byte]);
553 - def call(self,adr):
554 """Call to an address."""
555 self.writecmd(0,0x30,2,
556 [adr&0xFF,(adr>>8)&0xFF]);
558 """Execute supplied code."""
559 self.writecmd(0,0x31,2,
560 code);
562 """Read a byte of memory from the monitor."""
563 self.data=[address&0xff,address>>8];
564 self.writecmd(0,0x02,2,self.data);
565
566 return ord(self.data[0]);
568 """Read a word of memory from the monitor."""
569 return self.MONpeek8(address)+(self.MONpeek8(address+1)<<8);
570 - def peek(self,address):
571 """Read a word of memory from the monitor."""
572 return self.MONpeek8(address)+(self.MONpeek8(address+1)<<8);
574 """Read a word of memory from the monitor."""
575 print "EEPROM peeking not supported for the monitor.";
576
578 """Read a value by its symbol name."""
579
580 reg=self.symbols.get(name);
581 return self.peek8(reg,"data");
583 """Write a value by its symbol name."""
584
585 reg=self.symbols.get(name);
586 return self.pokebyte(reg,val);
587 - def pokebyte(self,address,value,memory="vn"):
588 """Set a byte of memory by the monitor."""
589 self.data=[address&0xff,address>>8,value];
590 self.writecmd(0,0x03,3,self.data);
591 return ord(self.data[0]);
592 - def poke16(self,address,value):
593 """Set a word of memory by the monitor."""
594 self.MONpoke16(address,value);
596 """Set a word of memory by the monitor."""
597 self.pokebyte(address,value&0xFF);
598 self.pokebyte(address,(value>>8)&0xFF);
599 return value;
601 """Set a secret word for later retreival. Used by glitcher."""
602
603
604 print "Secret setting is not yet suppored for this target.";
605 print "Aborting.";
606
608 """Get a secret word. Used by glitcher."""
609
610 print "Secret getting is not yet suppored for this target.";
611 print "Aborting.";
612 sys.exit();
613
615 i=begin;
616 while i<end:
617 print "%04x %04x" % (i, self.MONpeek16(i));
618 i+=2;
620 """Overwrite all of RAM with 0xBEEF."""
621 self.writecmd(0,0x90,0,self.data);
622 return;
624 """Determine how many bytes of RAM are unused by looking for 0xBEEF.."""
625 self.writecmd(0,0x91,0,self.data);
626 return ord(self.data[0])+(ord(self.data[1])<<8);
627
628
629 baudrates=[115200,
630 9600,
631 19200,
632 38400,
633 57600,
634 115200];
636 """Change the baud rate. TODO fix this."""
637 rates=self.baudrates;
638 self.data=[baud];
639 print "Changing FET baud."
640 self.serialport.write(chr(0x00));
641 self.serialport.write(chr(0x80));
642 self.serialport.write(chr(1));
643 self.serialport.write(chr(baud));
644
645 print "Changed host baud."
646 self.serialport.setBaudrate(rates[baud]);
647 time.sleep(1);
648 self.serialport.flushInput()
649 self.serialport.flushOutput()
650
651 print "Baud is now %i." % rates[baud];
652 return;
654 return ord(self.serialport.read(1));
656 for r in self.baudrates:
657 print "\nTrying %i" % r;
658 self.serialport.setBaudrate(r);
659
660 self.serialport.flushInput()
661 self.serialport.flushOutput()
662
663 for i in range(1,10):
664 self.readbyte();
665
666 print "Read %02x %02x %02x %02x" % (
667 self.readbyte(),self.readbyte(),self.readbyte(),self.readbyte());
668
670 """Self-test several functions through the monitor."""
671 print "Performing monitor self-test.";
672 self.monitorclocking();
673 for f in range(0,3000):
674 a=self.MONpeek16(0x0c00);
675 b=self.MONpeek16(0x0c02);
676 if a!=0x0c04 and a!=0x0c06:
677 print "ERROR Fetched %04x, %04x" % (a,b);
678 self.pokebyte(0x0021,0);
679 if self.MONpeek8(0x0021)!=0:
680 print "ERROR, P1OUT not cleared.";
681 self.pokebyte(0x0021,1);
682 if not self.monitorecho():
683 print "Echo test failed.";
684 print "Self-test complete.";
685 self.monitorclocking();
686
688 data="The quick brown fox jumped over the lazy dog.";
689 self.writecmd(self.MONITORAPP,0x81,len(data),data);
690 if self.data!=data:
691 if self.verbose:
692 print "Comm error recognized by monitorecho(), got:\n%s" % self.data;
693 return 0;
694 return 1;
695
700
702 print "Flashing LEDs"
703 self.writecmd(self.MONITORAPP,0xD0,0,"")
704 try:
705 print "Flashed %d LED." % ord(self.data)
706 except:
707 print "Unable to process response:", self.data
708 return 1
709
711 self.monitor_info()
712 old_value = self.besilent
713 self.besilent = True
714 self.writecmd(self.MONITORAPP, 0x82, 1, [int(full)]);
715 self.besilent = old_value
716
717
718 self.readcmd()
719 print "Build Date: %s" % self.data
720 print "Firmware apps:"
721 while True:
722 self.readcmd()
723 if self.count == 0:
724 break
725 print self.data
726 return 1;
727
729 """Return the 16-bit clocking value."""
730 return "0x%04x" % self.monitorgetclock();
731
733 """Set the clocking value."""
734 self.MONpoke16(0x56, clock);
736 """Get the clocking value."""
737 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'):
738 return 0xDEAD;
739
740 return self.MONpeek16(0x56);
741
742
743
745 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'):
746
747 return "Arduino";
748 else:
749 a=self.MONpeek8(0xff0);
750 b=self.MONpeek8(0xff1);
751 return "%02x%02x" % (a,b);
753 print "Locking Unsupported.";
755 print "Erasure Unsupported.";
761 print "Unimplemented.";
762 return;
764 print "Unimplemented.";
765 return;
767 print "Unimplemented.";
768 return;
770 print "Unimplemented.";
771 return;
773 print "Unimplemented.";
774 return 0xdead;
776 """Flash an intel hex file to code memory."""
777 print "Flash not implemented.";
778 - def dump(self,file,start=0,stop=0xffff):
779 """Dump an intel hex file from code memory."""
780 print "Dump not implemented.";
781 - def peek32(self,address, memory="vn"):
782 """Peek 32 bits."""
783 return (self.peek16(address,memory)+
784 (self.peek16(address+2,memory)<<16));
785 - def peek16(self,address, memory="vn"):
786 """Peek 16 bits of memory."""
787 return (self.peek8(address,memory)+
788 (self.peek8(address+1,memory)<<8));
789 - def peek8(self,address, memory="vn"):
790 """Peek a byte of memory."""
791 return self.MONpeek8(address);
792 - def peekblock(self,address,length,memory="vn"):
793 """Return a block of data."""
794 data=range(0,length);
795 for foo in range(0,length):
796 data[foo]=self.peek8(address+foo,memory);
797 return data;
798 - def pokeblock(self,address,bytes,memory="vn"):
799 """Poke a block of a data into memory at an address."""
800 for foo in bytes:
801 self.pokebyte(address,foo,memory);
802 address=address+1;
803 return;
805 """Load symbols from a file."""
806 return;
807