Package killerbee :: Module GoodFET
[hide private]
[frames] | no frames]

Source Code for Module killerbee.GoodFET

  1  #!/usr/bin/env python 
  2  # GoodFET Client Library 
  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, os; 
  9  import sqlite3; 
 10   
 11  fmt = ("B", "<H", None, "<L") 
 12   
13 -def getClient(name="GoodFET"):
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
26 -class SymbolTable:
27 """GoodFET Symbol Table""" 28 db=sqlite3.connect(":memory:"); 29
30 - def __init__(self, *args, **kargs):
31 self.db.execute("create table if not exists symbols(adr,name,memory,size,comment);");
32 - def get(self,name):
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 #print "Found it."; 39 sys.stdout.flush(); 40 return row[0]; 41 #print "No dice."; 42 except:# sqlite3.OperationalError: 43 #print "SQL error."; 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 #print "Set %s=%s." % (name,adr);
51 -class GoodFETbtser:
52 """py-bluez class for emulating py-serial."""
53 - def __init__(self,btaddr):
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 #TODO switch to wildcards. 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 # Manually use the portnumber. 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); #IMPORTANT Must be patient. 79 80 ##This is what we'd do for a normal reset. 81 #str=""; 82 #while not str.endswith("goodfet.sf.net/"): 83 # str=self.read(64); 84 # print str; 85 86 # Instead, just return and hope for the best. 87 return;
88
89 - def write(self,msg):
90 """Send traffic.""" 91 import time; 92 self.sock.send(msg); 93 #time.sleep(0.1); 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
102 -class GoodFET:
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
116 - def __init__(self, *args, **kargs):
117 self.data=[0];
118 - def getConsole(self):
119 from GoodFETConsole import GoodFETConsole; 120 return GoodFETConsole(self);
121 - def name2adr(self,name):
122 return self.symbols.get(name);
123 - def timeout(self):
124 print "timeout\n";
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 #self.verbose=True; #For debugging BT. 138 self.serialport=GoodFETbtser(port);
139
140 - def pyserInit(self, port, timeout, attemptlimit):
141 """Open the serial port""" 142 # Make timeout None to wait forever, 0 for non-blocking mode. 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 #print "Using FTDI port %s" % port 175 except: 176 #Do nothing. 177 a=1; 178 179 baud=115200; 180 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'): 181 baud=19200; #Slower, for now. 182 self.serialport = serial.Serial( 183 port, 184 #9600, 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 #while self.data!="http://goodfet.sf.net/": 196 #print "'%s'!=\n'%s'" % (self.data,"http://goodfet.sf.net/"); 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.") # No newline 205 sys.stdout.flush() 206 self.verbose=True # Something isn't going right, give the user more info 207 elif attempts > 100 and attempts % 10 == 0: 208 sys.stdout.write('.') 209 sys.stdout.flush() 210 #self.serialport.flushInput() 211 #self.serialport.flushOutput() 212 213 #TelosB reset, prefer software to I2C SPST Switch. 214 if (os.environ.get("board")=='telosb'): 215 #print "TelosB Reset"; 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 #Not needed for the apimote2 221 #Explicitly set RTS and DTR to halt board. 222 self.serialport.setRTS(1); 223 self.serialport.setDTR(1); 224 #RTS pin, not DTR is used for reset. 225 self.serialport.setRTS(0); 226 else: 227 #Explicitly set RTS and DTR to halt board. 228 self.serialport.setRTS(1); 229 self.serialport.setDTR(1); 230 #Drop DTR, which is !RST, low to begin the app. 231 self.serialport.setDTR(0); 232 233 #self.serialport.write(chr(0x80)); 234 #self.serialport.write(chr(0x80)); 235 #self.serialport.write(chr(0x80)); 236 #self.serialport.write(chr(0x80)); 237 238 239 #self.serialport.flushInput() 240 #self.serialport.flushOutput() 241 #time.sleep(60); 242 attempts=attempts+1; 243 self.readcmd(); #Read the first command. 244 #print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data); 245 if self.verb!=0x7f: 246 #Retry again. This usually times out, but helps connect. 247 self.readcmd(); 248 #print "Retry got %02x,%02x:'%s'" % (self.app,self.verb,self.data); 249 #Here we have a connection, but maybe not a good one. 250 #print "We have a connection." 251 connected=1; 252 if attempts >= 100: 253 print "" # Add a newline 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);
266 - def serClose(self):
267 self.serialport.close();
268
269 - def telosSetSCL(self, level):
270 '''Helper function for support of the TelosB platform.''' 271 self.serialport.setRTS(not level)
272 - def telosSetSDA(self, level):
273 '''Helper function for support of the TelosB platform.''' 274 self.serialport.setDTR(not level)
275 - def telosI2CStart(self):
276 '''Helper function for support of the TelosB platform.''' 277 self.telosSetSDA(1) 278 self.telosSetSCL(1) 279 self.telosSetSDA(0)
280 - def telosI2CStop(self):
281 '''Helper function for support of the TelosB platform.''' 282 self.telosSetSDA(0) 283 self.telosSetSCL(1) 284 self.telosSetSDA(1)
285 - def telosI2CWriteBit(self, bit):
286 '''Helper function for support of the TelosB platform.''' 287 self.telosSetSCL(0) 288 self.telosSetSDA(bit) 289 time.sleep(2e-6) 290 self.telosSetSCL(1) 291 time.sleep(1e-6) 292 self.telosSetSCL(0)
293 - def telosI2CWriteByte(self, byte):
294 '''Helper function for support of the TelosB platform.''' 295 self.telosI2CWriteBit( byte & 0x80 ); 296 self.telosI2CWriteBit( byte & 0x40 ); 297 self.telosI2CWriteBit( byte & 0x20 ); 298 self.telosI2CWriteBit( byte & 0x10 ); 299 self.telosI2CWriteBit( byte & 0x08 ); 300 self.telosI2CWriteBit( byte & 0x04 ); 301 self.telosI2CWriteBit( byte & 0x02 ); 302 self.telosI2CWriteBit( byte & 0x01 ); 303 self.telosI2CWriteBit( 0 ); # "acknowledge"
304 - def telosI2CWriteCmd(self, addr, cmdbyte):
305 '''Helper function for support of the TelosB platform.''' 306 self.telosI2CStart() 307 self.telosI2CWriteByte( 0x90 | (addr << 1) ) 308 self.telosI2CWriteByte( cmdbyte ) 309 self.telosI2CStop()
310
311 - def bslResetZ1(self, invokeBSL=0):
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 #if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) 320 if invokeBSL: 321 #sys.stderr.write("in Z1 bsl reset...\n") 322 time.sleep(0.1) 323 self.writepicROM(0xFF, 0xFF) 324 time.sleep(0.1) 325 #sys.stderr.write("z1 bsl reset done...\n") 326 else: 327 #sys.stderr.write("in Z1 reset...\n") 328 time.sleep(0.1) 329 self.writepicROM(0xFF, 0xFE) 330 time.sleep(0.1)
331 #sys.stderr.write("z1 reset done...\n") 332
333 - def writepicROM(self, address, data):
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 #print s 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 #k = 1 350 #while not self.serial.getCTS(): 351 # pass 352 #time.sleep(0.1) 353 return recbuf
354 - def readpicROM(self, address):
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 #time.sleep(0.1) 366 return recbuf
367 368 #This seems more reliable when slowed.
369 - def picROMclock(self, masterout, slow = True):
370 #print "setting masterout to "+str(masterout) 371 self.serialport.setRTS(masterout) 372 self.serialport.setDTR(1) 373 #time.sleep(0.02) 374 self.serialport.setDTR(0) 375 if slow: 376 time.sleep(0.02) 377 return self.serialport.getCTS()
378
379 - def picROMfastclock(self, masterout):
380 #print "setting masterout to "+str(masterout) 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
387 - def telosBReset(self, invokeBSL=0):
388 '''Helper function for support of the TelosB platform.''' 389 # "BSL entry sequence at dedicated JTAG pins" 390 # rst !s0: 0 0 0 0 1 1 391 # tck !s1: 1 0 1 0 0 1 392 # s0|s1: 1 3 1 3 2 0 393 394 # "BSL entry sequence at shared JTAG pins" 395 # rst !s0: 0 0 0 0 1 1 396 # tck !s1: 0 1 0 1 1 0 397 # s0|s1: 3 1 3 1 0 2 398 399 if invokeBSL: 400 self.telosI2CWriteCmd(0,1) 401 self.telosI2CWriteCmd(0,3) 402 self.telosI2CWriteCmd(0,1) 403 self.telosI2CWriteCmd(0,3) 404 self.telosI2CWriteCmd(0,2) 405 self.telosI2CWriteCmd(0,0) 406 else: 407 self.telosI2CWriteCmd(0,3) 408 self.telosI2CWriteCmd(0,2) 409 410 # This line was not defined inside the else: block, not sure where it 411 # should be however 412 self.telosI2CWriteCmd(0,0) 413 time.sleep(0.250) #give MSP430's oscillator time to stabilize 414 self.serialport.flushInput() #clear buffers
415
416 - def getbuffer(self,size=0x1c00):
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 #if data!=None: 426 # count=len(data); #Initial count ignored. 427 428 #print "TX %02x %02x %04x" % (app,verb,count); 429 430 #little endian 16-bit length 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 #print "count=%02x, len(data)=%04x" % (count,len(data)); 438 439 if count!=0: 440 if(isinstance(data,list)): 441 for i in range(0,count): 442 #print "Converting %02x at %i" % (data[i],i) 443 data[i]=chr(data[i]); 444 #print type(data); 445 outstr=''.join(data); 446 self.serialport.write(outstr); 447 if not self.besilent: 448 return self.readcmd() 449 else: 450 return []
451
452 - def readcmd(self):
453 """Read a reply from the GoodFET.""" 454 while 1:#self.serialport.inWaiting(): # Loop while input data is available 455 try: 456 #print "Reading..."; 457 self.app=ord(self.serialport.read(1)); 458 #print "APP=%02x" % self.app; 459 self.verb=ord(self.serialport.read(1)); 460 461 #Fixes an obscure bug in the TelosB. 462 if self.app==0x00: 463 while self.verb==0x00: 464 self.verb=ord(self.serialport.read(1)); 465 466 #print "VERB=%02x" % self.verb; 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 #Debugging string; print, but wait. 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 #Do nothing, just wait so there's no timeout. 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 #print "This shouldn't happen after syncing. Exiting for safety."; 493 #sys.exit(-1) 494 return self.data;
495 496 #Glitching stuff.
497 - def glitchApp(self,app):
498 """Glitch into a device by its application.""" 499 self.data=[app&0xff]; 500 self.writecmd(self.GLITCHAPP,0x80,1,self.data);
501 #return ord(self.data[0]);
502 - def glitchVerb(self,app,verb,data):
503 """Glitch during a transaction.""" 504 if data==None: data=[]; 505 self.data=[app&0xff, verb&0xFF]+data; 506 self.writecmd(self.GLITCHAPP,0x81,len(self.data),self.data);
507 #return ord(self.data[0]);
508 - def glitchstart(self):
509 """Glitch into the AVR application.""" 510 self.glitchVerb(self.APP,0x20,None);
511 - def glitchstarttime(self):
512 """Measure the timer of the START verb.""" 513 return self.glitchTime(self.APP,0x20,None);
514 - def glitchTime(self,app,verb,data):
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;
523 - def glitchVoltages(self,low=0x0880, high=0x0fff):
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 #return ord(self.data[0]);
529 - def glitchRate(self,count=0x0800):
530 """Set glitching count period.""" 531 self.data=[count&0xff, (count>>8)&0xff]; 532 self.writecmd(self.GLITCHAPP,0x91,2, 533 self.data);
534 #return ord(self.data[0]); 535 536 #Monitor stuff
537 - def silent(self,s=0):
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;
543 - def mon_connected(self):
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]);
557 - def execute(self,code):
558 """Execute supplied code.""" 559 self.writecmd(0,0x31,2,#len(code), 560 code);
561 - def MONpeek8(self,address):
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 #self.readcmd(); 566 return ord(self.data[0]);
567 - def MONpeek16(self,address):
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);
573 - def eeprompeek(self,address):
574 """Read a word of memory from the monitor.""" 575 print "EEPROM peeking not supported for the monitor.";
576 #return self.MONpeek8(address)+(self.MONpeek8(address+1)<<8);
577 - def peekbysym(self,name):
578 """Read a value by its symbol name.""" 579 #TODO include memory in symbol. 580 reg=self.symbols.get(name); 581 return self.peek8(reg,"data");
582 - def pokebysym(self,name,val):
583 """Write a value by its symbol name.""" 584 #TODO include memory in symbol. 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);
595 - def MONpoke16(self,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;
600 - def setsecret(self,value):
601 """Set a secret word for later retreival. Used by glitcher.""" 602 #self.eeprompoke(0,value); 603 #self.eeprompoke(1,value); 604 print "Secret setting is not yet suppored for this target."; 605 print "Aborting.";
606
607 - def getsecret(self):
608 """Get a secret word. Used by glitcher.""" 609 #self.eeprompeek(0); 610 print "Secret getting is not yet suppored for this target."; 611 print "Aborting."; 612 sys.exit();
613
614 - def dumpmem(self,begin,end):
615 i=begin; 616 while i<end: 617 print "%04x %04x" % (i, self.MONpeek16(i)); 618 i+=2;
619 - def monitor_ram_pattern(self):
620 """Overwrite all of RAM with 0xBEEF.""" 621 self.writecmd(0,0x90,0,self.data); 622 return;
623 - def monitor_ram_depth(self):
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 #Baud rates 629 baudrates=[115200, 630 9600, 631 19200, 632 38400, 633 57600, 634 115200];
635 - def setBaud(self,baud):
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;
653 - def readbyte(self):
654 return ord(self.serialport.read(1));
655 - def findbaud(self):
656 for r in self.baudrates: 657 print "\nTrying %i" % r; 658 self.serialport.setBaudrate(r); 659 #time.sleep(1); 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
669 - def monitortest(self):
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); #Drop LED 679 if self.MONpeek8(0x0021)!=0: 680 print "ERROR, P1OUT not cleared."; 681 self.pokebyte(0x0021,1); #Light LED 682 if not self.monitorecho(): 683 print "Echo test failed."; 684 print "Self-test complete."; 685 self.monitorclocking();
686
687 - def monitorecho(self):
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
696 - def monitor_info(self):
697 print "GoodFET with %s MCU" % self.infostring(); 698 print "Clocked at %s" % self.monitorclocking(); 699 return 1;
700
701 - def testleds(self):
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
710 - def monitor_list_apps(self, full=False):
711 self.monitor_info() 712 old_value = self.besilent 713 self.besilent = True # turn off automatic call to readcmd 714 self.writecmd(self.MONITORAPP, 0x82, 1, [int(full)]); 715 self.besilent = old_value 716 717 # read the build date string 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
728 - def monitorclocking(self):
729 """Return the 16-bit clocking value.""" 730 return "0x%04x" % self.monitorgetclock();
731
732 - def monitorsetclock(self,clock):
733 """Set the clocking value.""" 734 self.MONpoke16(0x56, clock);
735 - def monitorgetclock(self):
736 """Get the clocking value.""" 737 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'): 738 return 0xDEAD; 739 #Check for MSP430 before peeking this. 740 return self.MONpeek16(0x56);
741 742 # The following functions ought to be implemented in 743 # every client.
744 - def infostring(self):
745 if(os.environ.get("platform")=='arduino' or os.environ.get("board")=='arduino'): 746 #TODO implement in the ardunio client and remove special case from here 747 return "Arduino"; 748 else: 749 a=self.MONpeek8(0xff0); 750 b=self.MONpeek8(0xff1); 751 return "%02x%02x" % (a,b);
752 - def lock(self):
753 print "Locking Unsupported.";
754 - def erase(self):
755 print "Erasure Unsupported.";
756 - def setup(self):
757 return;
758 - def start(self):
759 return;
760 - def test(self):
761 print "Unimplemented."; 762 return;
763 - def status(self):
764 print "Unimplemented."; 765 return;
766 - def halt(self):
767 print "Unimplemented."; 768 return;
769 - def resume(self):
770 print "Unimplemented."; 771 return;
772 - def getpc(self):
773 print "Unimplemented."; 774 return 0xdead;
775 - def flash(self,file):
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); #monitor
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;
804 - def loadsymbols(self):
805 """Load symbols from a file.""" 806 return;
807