From a6afe092f45e72e65198bf6fbe07e8da40706970 Mon Sep 17 00:00:00 2001 From: travisutk Date: Tue, 19 Jan 2010 17:32:22 +0000 Subject: [PATCH] Closer to reliable AVR glitching. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@270 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFET.py | 13 +++- client/GoodFETAVR.py | 15 +++++ client/goodfet.avr | 26 ++++++-- client/goodfet.bsl | 110 +++++++++++++++++----------------- firmware/apps/avr/avr.c | 2 +- firmware/apps/glitch/glitch.c | 5 ++ 6 files changed, 108 insertions(+), 63 deletions(-) diff --git a/client/GoodFET.py b/client/GoodFET.py index 5236b04..654995b 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -113,16 +113,23 @@ class GoodFET: self.data=self.serialport.read(self.count); return self.data; #Glitching stuff. - def glitchAPP(self,app): + def glitchApp(self,app): """Glitch into a device by its application.""" self.data=[app&0xff]; self.writecmd(self.GLITCHAPP,0x80,1,self.data); #return ord(self.data[0]); - def glitchVERB(self,app,verb, data): - """Glitch during a transaction..""" + def glitchVerb(self,app,verb,data): + """Glitch during a transaction.""" + if data==None: data=[]; self.data=[app&0xff, verb&0xFF]+data; self.writecmd(self.GLITCHAPP,0x81,len(self.data),self.data); #return ord(self.data[0]); + def glitchTime(self,app,verb,data): + """Time the execution of a verb.""" + if data==None: data=[]; + self.data=[app&0xff, verb&0xFF]+data; + self.writecmd(self.GLITCHAPP,0x82,len(self.data),self.data); + return ord(self.data[0])+(ord(self.data[1])<<8); def glitchVoltages(self,low=0x0880, high=0x0fff): """Set glitching voltages. (0x0fff is max.)""" self.data=[low&0xff, (low>>8)&0xff, diff --git a/client/GoodFETAVR.py b/client/GoodFETAVR.py index ee5b180..d950b53 100644 --- a/client/GoodFETAVR.py +++ b/client/GoodFETAVR.py @@ -67,6 +67,21 @@ class GoodFETAVR(GoodFET): def start(self): """Start the connection.""" self.writecmd(self.AVRAPP,0x20,0,None); + def glitchstart(self): + """Glitch into the AVR application.""" + self.glitchVerb(self.AVRAPP,0x20,None); + def glitchstarttime(self): + """Measure the timer of the START verb.""" + return self.glitchTime(self.AVRAPP,0x20,None); + def forcestart(self): + """Forcibly start a connection.""" + + for i in range(0x880,0xfff): + #self.glitchVoltages(0x880, i); + self.start(); + bits=self.lockbits(); + print "At %04x, Lockbits: %02x" % (i,bits); + if(bits==0xFF): return; def erase(self): """Erase the target chip.""" self.writecmd(self.AVRAPP,0xF0,0,None); diff --git a/client/goodfet.avr b/client/goodfet.avr index 2418854..5eee753 100755 --- a/client/goodfet.avr +++ b/client/goodfet.avr @@ -28,11 +28,12 @@ client.start(); if(sys.argv[1]=="glitch"): print "Identifies as %s" % client.identstr(); client.glitchVoltages(0x880, 0xfff); - for i in range(1,20): + for i in range(1,2000): client.start(); - print "Identifies as %s, fused 0x%02x" % ( + print "Identifies as %s, fused 0x%02x; eeprom(0)=%02x" % ( client.identstr(), - client.lockbits()); + client.lockbits(), + client.eeprompeek(0)); if(sys.argv[1]=="glitchgraph"): print "Identifies as %s" % client.identstr(); for voltage in range(0x860,0x890,5): @@ -50,7 +51,7 @@ if(sys.argv[1]=="glitchgraph"): print "%04x %s" % (voltage,str); #print "%f, %i" % (voltage*(3.3/4096.0),count); if(sys.argv[1]=="info"): - print "Identifies as %s" % client.identstr(); + print "Identifies as %s, lock=%02x" % (client.identstr(),client.lockbits()); if(sys.argv[1]=="erase"): print "Erasing %s" % client.identstr(); client.erase(); @@ -58,7 +59,22 @@ if(sys.argv[1]=="lockbits"): print "Lockbits are 0x%02x" % client.lockbits(); if(len(sys.argv)>2): print "Lockbits set 0x%02x" % client.setlockbits(int(sys.argv[2],16)); -#if(sys.argv[1]=="lock"): +if(sys.argv[1]=="lock"): + client.setlockbits(0xFC); + +if(sys.argv[1]=="unlock"): + print "Identifies as %s" % client.identstr(); + client.glitchVoltages(0x880, 0xfff); + for i in range(1,20): + client.start(); + print "Identifies as %s, fused 0x%02x; eeprom(0)=%02x" % ( + client.identstr(), + client.lockbits(), + client.eeprompeek(0)); + if(client.lockbits()==0xFF): + client.setlockbits(0xFF); + print "Chip unlocked!" + exit(); #if(sys.argv[1]=="unlock"): diff --git a/client/goodfet.bsl b/client/goodfet.bsl index 458bedd..788e3f9 100755 --- a/client/goodfet.bsl +++ b/client/goodfet.bsl @@ -284,9 +284,9 @@ class LowLevel: #used for some hardware self.invertRST = 0 self.invertTEST = 0 - self.swapRSTTEST = 0 - self.telosLatch = 0 - self.telosI2C = 0 + self.swapRSTTEST = 0 + self.telosLatch = 0 + self.telosI2C = 0 self.protocolMode = self.MODE_BSL self.BSLMemAccessWarning = 0 #Default: no warning. @@ -490,22 +490,22 @@ class LowLevel: self.serialport.setDTR(not level) def telosI2CStart(self): - self.telosSetSDA(1) - self.telosSetSCL(1) - self.telosSetSDA(0) + self.telosSetSDA(1) + self.telosSetSCL(1) + self.telosSetSDA(0) def telosI2CStop(self): - self.telosSetSDA(0) - self.telosSetSCL(1) - self.telosSetSDA(1) + self.telosSetSDA(0) + self.telosSetSCL(1) + self.telosSetSDA(1) def telosI2CWriteBit(self, bit): - self.telosSetSCL(0) - self.telosSetSDA(bit) + self.telosSetSCL(0) + self.telosSetSDA(bit) time.sleep(2e-6) - self.telosSetSCL(1) + self.telosSetSCL(1) time.sleep(1e-6) - self.telosSetSCL(0) + self.telosSetSCL(0) def telosI2CWriteByte(self, byte): self.telosI2CWriteBit( byte & 0x80 ); @@ -519,36 +519,38 @@ class LowLevel: self.telosI2CWriteBit( 0 ); # "acknowledge" def telosI2CWriteCmd(self, addr, cmdbyte): - self.telosI2CStart() + self.telosI2CStart() self.telosI2CWriteByte( 0x90 | (addr << 1) ) - self.telosI2CWriteByte( cmdbyte ) - self.telosI2CStop() + self.telosI2CWriteByte( cmdbyte ) + self.telosI2CStop() def telosBReset(self,invokeBSL=0): - - # "BSL entry sequence at dedicated JTAG pins" + # "BSL entry sequence at dedicated JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 1 0 1 0 0 1 + # tck !s1: 1 0 1 0 0 1 # s0|s1: 1 3 1 3 2 0 - # "BSL entry sequence at shared JTAG pins" + # "BSL entry sequence at shared JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 0 1 0 1 1 0 + # tck !s1: 0 1 0 1 1 0 # s0|s1: 3 1 3 1 0 2 - if invokeBSL: - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) - else: - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) + if invokeBSL: + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + else: + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + + # This line was not defined inside the else: block, not sure where it + # should be however + self.telosI2CWriteCmd(0,0) time.sleep(0.250) #give MSP430's oscillator time to stabilize - self.serialport.flushInput() #clear buffers + self.serialport.flushInput() #clear buffers def bslReset(self, invokeBSL=0): """Applies BSL entry sequence on RST/NMI and TEST/VPP pins @@ -559,19 +561,19 @@ class LowLevel: RST is inverted twice on boot loader hardware TEST is inverted (only once) Need positive voltage on DTR, RTS for power-supply of hardware""" - if self.telosI2C: - self.telosBReset(invokeBSL) - return + if self.telosI2C: + self.telosBReset(invokeBSL) + return if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) self.SetRSTpin(1) #power suply self.SetTESTpin(1) #power suply time.sleep(0.250) #charge capacitor on boot loader hardware - if self.telosLatch: - self.SetTESTpin(0) - self.SetRSTpin(0) - self.SetTESTpin(1) + if self.telosLatch: + self.SetTESTpin(0) + self.SetRSTpin(0) + self.SetTESTpin(1) self.SetRSTpin(0) #RST pin: GND if invokeBSL: @@ -1409,11 +1411,11 @@ def main(itest=1): "upload=", "download=", "size=", "hex", "bin", "intelhex", "titext", "notimeout", "bsl=", "speed=", "bslversion", "f1x", "f2x", "f4x", "invert-reset", "invert-test", - "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", + "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", "tmote","no-BSL-download", "force-BSL-download", "slow", "dumpivt", "dumpinfo", "fromweb", - "goodfet30", "goodfet20", "goodfet10" - ] + "goodfet30", "goodfet20", "goodfet10" + ] ) except getopt.GetoptError: # print help information and exit: @@ -1553,25 +1555,25 @@ def main(itest=1): bsl.invertTEST = 1 bsl.swapRSTTEST = 1 bsl.telosLatch = 1 - elif o in ("--goodfet10", ): - bsl.invertRST = 1 - bsl.invertTEST = 1 - elif o in ("--goodfet20", ): - bsl.invertRST = 1 - bsl.invertTEST = 1 - elif o in ("--goodfet30", ): - bsl.invertRST = 1 - bsl.invertTEST = 0 + elif o in ("--goodfet10", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet20", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet30", ): + bsl.invertRST = 1 + bsl.invertTEST = 0 elif o in ("--telosb", ): bsl.swapRSTTEST = 1 bsl.telosI2C = 1 mayuseBSL = 0 - speed = 38400 + speed = 38400 elif o in ("--tmote", ): bsl.swapRSTTEST = 1 bsl.telosI2C = 1 mayuseBSL = 0 - speed = 38400 + speed = 38400 elif o in ("--no-BSL-download", ): mayuseBSL = 0 elif o in ("--force-BSL-download", ): diff --git a/firmware/apps/avr/avr.c b/firmware/apps/avr/avr.c index 9db6ce4..5b5fcae 100644 --- a/firmware/apps/avr/avr.c +++ b/firmware/apps/avr/avr.c @@ -154,7 +154,7 @@ void avrhandle(unsigned char app, case START: avrconnect(); txdata(app,verb,0); - break; + break;//Used to fall through here. case AVR_PEEKSIG: for(i=0;i<4;i++) cmddata[i]=avr_sig(i); diff --git a/firmware/apps/glitch/glitch.c b/firmware/apps/glitch/glitch.c index 9ddcc8c..dc79d31 100644 --- a/firmware/apps/glitch/glitch.c +++ b/firmware/apps/glitch/glitch.c @@ -67,6 +67,11 @@ interrupt(TIMERA0_VECTOR) Timer_A (void) //debugstr("Glitching."); DAC12_0DAT = 0;//glitchL; asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + DAC12_0DAT = glitchH; //DAC12_0DAT = glitchL; /* -- 2.20.1