# * flash manipulation (probably need to get the specific chip for this one)
# * set security (chip-specific)
-import sys, binascii, struct, time
+import sys
+import time
+import struct
+
from GoodFET import GoodFET
from intelhex import IntelHex
PM_abt = 0b10111
PM_und = 0b11011
PM_sys = 0b11111
+
proc_modes = {
0: ("UNKNOWN, MESSED UP PROCESSOR MODE","fsck", "This should Never happen. MCU is in funky state!"),
PM_usr: ("User Processor Mode", "usr", "Normal program execution mode"),
def debugstr(strng):
print >>sys.stderr,(strng)
+
def PSRdecode(psrval):
output = [ "(%s mode)"%proc_modes[psrval&0x1f][1] ]
for x in xrange(5,32):
return " ".join(output)
fmt = [None, "B", "<H", None, "<L", None, None, None, "<Q"]
+
def chop(val,byts):
s = struct.pack(fmt[byts], val)
return [ord(b) for b in s ]
-class GoodFETARM(GoodFET):
+class GoodFETARM7(GoodFET):
"""A GoodFET variant for use with ARM7TDMI microprocessor."""
def __init__(self):
GoodFET.__init__(self)
self.current_dbgstate = 0xffffffff
self.flags = 0xffffffff
self.nothing = 0xffffffff
+ self.stored_regs = []
def __del__(self):
try:
if (self.ARMget_dbgstate()&9) == 9:
ver = (ident >> 28)
partno = (ident >> 12) & 0xffff
mfgid = (ident >> 1) & 0x7ff
- return "Chip IDCODE: 0x%x\n\tver: %x\n\tpartno: %x\n\tmfgid: %x\n" % (ident, ver, partno, mfgid);
+ return "Chip IDCODE: 0x%x\tver: %x\tpartno: %x\tmfgid: %x" % (ident, ver, partno, mfgid);
def ARMeice_write(self, reg, val):
data = chop(val,4)
data.extend([reg])
self.ARMset_register(0,r0)
return retval
def ARMcapture_system_state(self, pcoffset):
+ self.c0Data, self.flags, self.c0Addr = self.ARMchain0(0)
if self.ARMget_dbgstate() & DBG_TBIT:
pcoffset += 8
else:
pcoffset += 4
self.storedPC = self.ARMget_register(15) + pcoffset
self.last_dbg_state = self.ARMget_dbgstate()
- def ARMhaltcpu(self):
+ self.cpsr = self.ARMget_regCPSR()
+ print "ARMcapture_system_state: stored pc: 0x%x last_dbg_state: 0x%x" % (self.storedPC, self.last_dbg_state)
+
+ #def ARMhaltcpu(self):
+ def halt(self):
"""Halt the CPU."""
- if not(self.ARMget_dbgstate()&1):
- self.ARMset_dbgctrl(2)
- if (self.ARMwaitDBG() == 0):
- raise Exception("Timeout waiting to enter DEBUG mode on HALT")
- self.ARMset_dbgctrl(0)
- self.ARMcapture_system_state(PCOFF_DBGRQ)
- if self.last_dbg_state&0x10:
- self.storedPC = self.THUMBgetPC()
- else:
- self.storedPC = self.ARMget_register(15)
- self.storedPC, self.flags, self.nothing = self.ARMchain0(0)
+ if self.ARMget_dbgstate()&DBG_DBGACK:
+ if not len(self.stored_regs):
+ #print "stored regs: " + repr(self.stored_regs)
+ self.stored_regs = self.ARMget_registers()[:15]
+ print self.print_stored_registers()
+ return
+ print "halting cpu"
+ self.ARMset_dbgctrl(2)
+ if (self.ARMwaitDBG() == 0):
+ raise Exception("Timeout waiting to enter DEBUG mode on HALT")
+ self.ARMset_dbgctrl(0)
+
+ self.ARMcapture_system_state(PCOFF_DBGRQ)
+ print "storedPC: %x (%x) flags: %x nothing: %x" % (self.storedPC, self.c0Data, self.flags, self.c0Addr)
if self.ARMget_dbgstate() & DBG_TBIT:
self.ARMsetModeARM()
if self.storedPC ^ 4:
self.ARMset_register(15,self.storedPC&0xfffffffc)
+ self.stored_regs = self.ARMget_registers()[:15]
+ #print "stored regs: " + repr(self.stored_regs)
+ #print self.print_stored_registers()
print "CPSR: (%s) %s"%(self.ARMget_regCPSRstr())
- halt = ARMhaltcpu
+ #halt = ARMhaltcpu
- def ARMreleasecpu(self):
+ #def ARMreleasecpu(self):
+ def resume(self):
"""Resume the CPU."""
- # restore registers FIXME: DO THIS
- if self.ARMget_dbgstate()&1 == 0:
+ # FIXME: restore CPSR
+ # FIXME: true up PC to exactly where we left off...
+ if not self.ARMget_dbgstate()&DBG_DBGACK:
return
- currentPC, self.currentflags, nothing = self.ARMchain0(self.storedPC,self.flags)
+ print "resume"
+ if len(self.stored_regs):
+ #print self.print_stored_registers()
+ self.ARMset_registers(self.stored_regs, 0x7fff)
+ else:
+ print "skipping restore of stored registers due to empty list ? WTFO?"
+
+ currentPC, self.currentflags, nothing = self.ARMchain0(self.storedPC,self.flags, self.c0Addr)
if not(self.flags & F_TBIT): # need to be in arm mode
if self.currentflags & F_TBIT: # currently in thumb mode
self.ARMsetModeARM()
self.ARM_nop(1)
#print hex(self.storedPC)
#print hex(self.ARMget_register(15))
- print hex(self.ARMchain0(self.storedPC,self.flags)[0])
+ #print hex(self.ARMchain0(self.storedPC,self.flags)[0])
+ self.ARMchain0(self.storedPC,self.flags)[0]
self.ARMdebuginstr(THUMB_INSTR_B_IMM | (0x7fc07fc),0)
self.ARM_nop(0)
self.ARMrestart()
- resume = ARMreleasecpu
+ #print >>sys.stderr,"Debug Status:\t%s\n" % self.statusstr()
+ #print >>sys.stderr,"CPSR: (%s) %s"%(self.ARMget_regCPSRstr())
+
+ #resume = ARMreleasecpu
def resettap(self):
self.writecmd(0x13, RESETTAP, 0,[])
def ARMsetModeARM(self):
r0 = None
if ((self.current_dbgstate & DBG_TBIT)):
- debugstr("=== Switching to ARM mode ===")
+ #debugstr("=== Switching to ARM mode ===")
self.ARM_nop(0)
self.ARMdebuginstr(THUMB_INSTR_BX_PC,0)
self.ARM_nop(0)
def ARMsetModeThumb(self): # needs serious work and truing
self.resettap()
- debugstr("=== Switching to THUMB mode ===")
+ #debugstr("=== Switching to THUMB mode ===")
if ( not (self.current_dbgstate & DBG_TBIT)):
self.storedPC |= 1
r0 = self.ARMget_register(0)
#print out
return ''.join(out)
+ def ARMprintChunk(self, adr, wordcount, verbose=False, width=8):
+ for string in self.ARMreprChunk(adr, wordcount, verbose=False, width=8):
+ sys.stdout.write(string)
+
+ def ARMreprChunk(self, adr, wordcount, verbose=False, width=8):
+ adr &= 0xfffffffc
+ endva = adr + (4*wordcount)
+ output = [ "Dwords from 0x%x through 0x%x" % (adr, endva) ]
+ idx = 0
+ for data in self.ARMreadChunk(adr, wordcount, verbose):
+ if (idx % width) == 0:
+ yield ( "\n0x%.8x\t" % (adr + (4*idx)) )
+ yield ( "%.8x " % (data) )
+ idx += 1
+
+ yield("\n")
+
def ARMreadChunk(self, adr, wordcount, verbose=True):
""" Only works in ARM mode currently
WARNING: Addresses must be word-aligned!
"""
regs = self.ARMget_registers()
self.ARMset_registers([0xdeadbeef for x in xrange(14)], 0xe)
- #output = []
count = wordcount
while (wordcount > 0):
if (verbose and wordcount%64 == 0): sys.stderr.write(".")
#print hex(adr)
# FIXME: handle the rest of the wordcount here.
self.ARMset_registers(regs,0xe)
- #return output
-
+
+ '''def ARMreadStream(self, adr, bytecount):
+ #data = [struct.unpack("<L", x) for x in self.ARMreadChunk(adr, (bytecount-1/4)+1)]
+ diff = adr % 4
+ address = adr - diff
+ data = [ struct.pack("<L", x) for x in self.ARMreadChunk(address, (bytecount-1/4)+1) ]
+ return "".join(data)[diff:bytecount]'''
+
ARMreadMem = ARMreadChunk
peek = ARMreadMem
- '''def ARMreadStream(self, adr, bytecount):
- data = [struct.unpack("<L", x) for x in self.ARMreadChunk(adr, (bytecount-1/4)+1)]
- return "".join(data)[:bytecount]
- '''
+
def ARMwriteChunk(self, adr, wordarray):
""" Only works in ARM mode currently
WARNING: Addresses must be word-aligned!
d1,b1,a1 = struct.unpack("<LQL",self.data)
return (a1,b1,d1)
- def start(self):
+ def start(self, ident=False):
"""Start debugging."""
self.writecmd(0x13,START,0,self.data)
- print >>sys.stderr,"Identifying Target:"
- ident=self.ARMidentstr()
- print >>sys.stderr,ident
- print >>sys.stderr,"Debug Status:\t%s\n" % self.statusstr()
+ if ident:
+ print >>sys.stderr,"Identifying Target:"
+ print >>sys.stderr, self.ARMidentstr()
+ print >>sys.stderr,"Debug Status:\t%s\n" % self.statusstr()
def stop(self):
"""Stop debugging."""
# print "Flashing buffer to 0x%06x" % adr
# self.writecmd(0x13,MASS_FLASH_PAGE,4,data)
+ def print_registers(self):
+ return [ hex(x) for x in self.ARMget_registers() ]
+
+ def print_stored_registers(self):
+ return [ hex(x) for x in self.stored_regs ]
+
+
+
+######### command line stuff #########
+from intelhex import IntelHex16bit, IntelHex
+
+def arm7_syntax():
+ print "Usage: %s verb [objects]\n" % sys.argv[0]
+ print "%s info" % sys.argv[0]
+ print "%s dump $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s erase" % sys.argv[0]
+ print "%s eraseinfo" % sys.argv[0]
+ print "%s flash $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s poke 0x$adr 0x$val" % sys.argv[0]
+ print "%s peek 0x$start [0x$stop]" % sys.argv[0]
+ print "%s reset" % sys.argv[0]
+ sys.exit()
+
+def arm7_main():
+ ''' this function should be called from command line app '''
+
+ #Initialize FET and set baud rate
+ client=GoodFETARM7()
+ client.serInit()
+
+ client.setup()
+ client.start()
+
+ arm7_cli_handler(client, sys.argv)
+
+def arm7_cli_handler(client, argv):
+ if(argv[1]=="info"):
+ client.halt()
+ print >>sys.stderr,"Identifying Target:"
+ print >>sys.stderr, self.ARMidentstr()
+ print >>sys.stderr,"Debug Status:\t%s\n" % self.statusstr()
+ client.resume()
+
+
+ if(argv[1]=="dump"):
+ f = sys.argv[2]
+ start=0x00000000
+ stop=0xFFFFFFFF
+ if(len(sys.argv)>3):
+ start=int(sys.argv[3],16)
+ if(len(sys.argv)>4):
+ stop=int(sys.argv[4],16)
+
+ print "Dumping from %04x to %04x as %s." % (start,stop,f)
+ #h = IntelHex16bit(None)
+ # FIXME: get mcu state and return it to that state
+ client.halt()
+
+ try:
+ h = IntelHex(None)
+ i=start
+ while i<=stop:
+ #data=client.ARMreadMem(i, 48)
+ data=client.ARMreadChunk(i, 48, verbose=0)
+ print "Dumped %06x."%i
+ for dword in data:
+ if i<=stop and dword != 0xdeadbeef:
+ h.puts( i, struct.pack("<I", dword) )
+ i+=4
+ # FIXME: get mcu state and return it to that state
+ except:
+ print "Unknown error during read. Writing results to output file."
+ print "Rename file with last address dumped %06x."%i
+ pass
+
+ client.resume()
+ h.write_hex_file(f)
+
+ '''
+ if(sys.argv[1]=="erase"):
+ print "Erasing main flash memory."
+ client.ARMmasserase()
+
+ if(sys.argv[1]=="eraseinfo"):
+ print "Erasing info memory."
+ client.ARMinfoerase()
+
+
+ '''
+ if(sys.argv[1]=="ivt"):
+ client.halt()
+ client.ARMprintChunk(0x0,0x20)
+ client.resume()
+
+ if(sys.argv[1]=="regs"):
+ client.halt()
+ for i in range(0,16):
+ print "r%i=%04x" % (i,client.ARMget_register(i))
+ client.resume()
+
+ if(sys.argv[1]=="flash"):
+ f=sys.argv[2]
+ start=0
+ stop=0x10000
+ if(len(sys.argv)>3):
+ start=int(sys.argv[3],16)
+ if(len(sys.argv)>4):
+ stop=int(sys.argv[4],16)
+
+ client.halt()
+ h = IntelHex16bit(f)
+
+ #Should this be default?
+ #Makes flashing multiple images inconvenient.
+ #client.ARMmasserase()
+
+ count=0; #Bytes in commit.
+ first=0
+ vals=[]
+ last=0; #Last address committed.
+ for i in h._buf.keys():
+ if((count>0x40 or last+2!=i) and count>0 and i&1==0):
+ #print "%i, %x, %x" % (len(vals), last, i)
+ client.ARMpokeflashblock(first,vals)
+ count=0
+ first=0
+ last=0
+ vals=[]
+ if(i>=start and i<stop and i&1==0):
+ val=h[i>>1]
+ if(count==0):
+ first=i
+ last=i
+ count+=2
+ vals+=[val&0xff,(val&0xff00)>>8]
+ if(i%0x100==0):
+ print "%04x" % i
+ if count>0: #last commit, ivt
+ client.ARMpokeflashblock(first,vals)
+ client.resume()
+
+ if(sys.argv[1]=="verify"):
+ f=sys.argv[2]
+ start=0
+ stop=0xFFFF
+ if(len(sys.argv)>3):
+ start=int(sys.argv[3],16)
+ if(len(sys.argv)>4):
+ stop=int(sys.argv[4],16)
+
+ client.halt()
+ h = IntelHex16bit(f)
+ for i in h._buf.keys():
+ if(i>=start and i<stop and i&1==0):
+ peek=client.peek(i)
+ if(h[i>>1]!=peek):
+ print "ERROR at %04x, found %04x not %04x"%(i,peek,h[i>>1])
+ if(i%0x100==0):
+ print "%04x" % i
+ client.resume()
+
+
+ if(sys.argv[1]=="peek"):
+ start = 0x0000
+ if(len(sys.argv)>2):
+ start=int(sys.argv[2],16)
+
+ stop = start+4
+ if(len(sys.argv)>3):
+ stop=int(sys.argv[3],16)
+
+ print "Peeking from %04x to %04x." % (start,stop)
+ client.halt()
+ for dword in client.ARMreadChunk(start, (stop-start)/4, verbose=0):
+ print "%.4x: %.8x" % (start, dword)
+ start += 4
+ client.resume()
+
+ if(sys.argv[1]=="poke"):
+ start=0x0000
+ val=0x00
+ if(len(sys.argv)>2):
+ start=int(sys.argv[2],16)
+ if(len(sys.argv)>3):
+ val=int(sys.argv[3],16)
+
+ print "Poking %06x to become %04x." % (start,val)
+ client.halt()
+ #???while client.ARMreadMem(start)[0]&(~val)>0:
+ client.ARMwriteChunk(start, [val])
+ print "Poked to %.8x" % client.ARMreadMem(start)[0]
+ client.resume()
+
+
+ if(sys.argv[1]=="reset"):
+ #Set PC to RESET vector's value.
+
+ #client.ARMsetPC(0x00000000)
+ #client.ARMset_regCPSR(0)
+ #client.ARMreleasecpu()
+ client.ARMresettarget(1000)
+
+ #client.ARMreleasecpu()
+ #client.ARMstop()
wse = (reg>>5)&1
nws = (reg>>2)&7
dbw = (reg&3)
+ return [ addr, csen, bat, tdf, pages, wse, nws, dbw]
+
+def ebi_csr_decode_str(reg):
+ (addr,
+ csen,
+ bat,
+ tdf,
+ pages,
+ wse,
+ nws,
+ dbw) = ebi_csr_decode(reg)
output = ["(register: %x)"%reg,
"Base Address: %s"%hex(addr<<20),
"Chip Select: %s"%("False","True")[csen],
def mcr_decode(mcr):
validAddrBits,maxAddrSpace,validCS,codeLabel = mcr_ale[mcr&7]
drp = mcr>>4
- output = ["Valid Address Bits: %s"%validAddrBits,
- "Maximum Address Space: %xMB"%maxAddrSpace,
+ #print hex(drp)
+ if drp and drp != 1:
+ drp = 2
+ return (validAddrBits, maxAddrSpace, validCS, codeLabel, drp)
+
+def mcr_decode_str(mcr):
+ ( validAddrBits, maxAddrSpace, validCS, codeLabel, drp) = mcr_decode(mcr)
+ output = [
+ "(register: %x)"%mcr,
+ "Valid Address Bits: %s"%validAddrBits,
+ "Maximum Address Space: 0x%x MB"%maxAddrSpace,
"Valid Chip Select: %s"%validCS,
"Code Label: %s"%codeLabel,
- ("Standard Read Protocol for all external memory devices enabled (EBI_DRP_STANDARD)","Early Read Protocol for all external memory devices enabled (EBI_DRP_EARLY)")[drp]
+ ("Standard Read Protocol for all external memory devices enabled (EBI_DRP_STANDARD)","Early Read Protocol for all external memory devices enabled (EBI_DRP_EARLY)","Invalid mcr")[drp]
]
return "\n".join(output)
def wd_omr_decode(omr):
- return "\n".join(["External Signal: %s"%("disabled","enabled")[(omr>>3)&1],
- "External Signal: %s"%("disabled","enabled")[(omr>>3)&1],
- "Interrupt: %s"%("disabled","enabled")[(omr>>2)&1],
- "Reset: %s"%("disabled","enabled")[(omr>>1)&1],
- "Watch Dog: %s"%("disabled","enabled")[(omr)&1],
+ return (omr>>4, (omr>>3)&1, (omr>>2)&1, (omr>>1)&1, omr&1)
+
+def wd_omr_decode_str(omr):
+ ( okey, esig, int, rst, wdog ) = wd_omr_decode(omr)
+ return "\n".join([
+ "Overflow Access Key (OKEY): %x"%(okey),
+ "External Signal (EXTEN): %s"%("disabled","enabled")[esig],
+ "Interrupt (IRQEN): %s"%("disabled","enabled")[int],
+ "Reset (RSTEN): %s"%("disabled","enabled")[rst],
+ "Watch Dog (WDEN): %s"%("disabled","enabled")[wdog],
])
+
def wd_cmr_decode(cmr):
return "MCK/%d"%(8,32,128,1024)[(cmr>>2)&0xf]
-class GoodFETAT91X40(GoodFETARM):
+class GoodFETAT91X40(GoodFETARM7):
def __init__(self):
- GoodFETARM.__init__(self)
+ GoodFETARM7.__init__(self)
self.usart0 = usart.USART(usart.USART0_BASE)
self.usart1 = usart.USART(usart.USART1_BASE)
+
+ def halt(self, disableWD=True):
+ GoodFETARM7.halt(self)
+ if not disableWD: return
+
+ #Disable Watch Dog
+ self.disableWatchDog()
+
+ def resume(self, enableWD=False):
+ GoodFETARM7.resume(self)
+ if not enableWD: return
+
+ self.enableWatchDog()
+
def getChipSelectReg(self, chipnum):
addr = EBI_BASE + (chipnum*4)
reg, = self.ARMreadChunk(addr,1)
return reg
def getChipSelectRegstr(self, chipnum):
+ return ebi_csr_decode_str(self.getChipSelectReg(chipnum))
+ def getChipSelectReglist(self, chipnum):
return ebi_csr_decode(self.getChipSelectReg(chipnum))
def setChipSelectReg(self, chipnum, value):
addr = EBI_BASE + (chipnum*4)
mcr, = self.ARMreadMem(EBI_MCR)
return mcr
def getMemoryControlRegisterstr(self):
- return mcr_decode(self.getMemoryControlRegister())
+ return mcr_decode_str(self.getMemoryControlRegister())
+ def getEBIMCR(self):
+ print "EBI Memory Control Register\n"
+ print self.getMemoryControlRegisterstr()
def getInterruptSourceModeReg(self, regnum):
regval = self.ARMreadMem(AIC_SMR[regnum][0])
def getWatchDogOverflowModeReg(self):
return self.ARMreadMem(WD_OMR)
def getWatchDogOverflowModeStr(self):
- return wd_omr_decode(self.getWatchDogOverflowModeReg())
- def setWatchDogOverflowModeReg(self, mode=0x2340):
- self.ARMwriteMem(WD_OMR, mode)
+ return wd_omr_decode_str(self.getWatchDogOverflowModeReg()[0])
+ def setWatchDogOverflowModeReg(self, mode=0x00002340):
+ self.ARMwriteMem(WD_OMR, [mode])
def getWatchDogClockModeReg(self):
- return self.ARMreadMem(WD_CMR)
+ return self.ARMreadMem(WD_CMR)[0]
def setWatchDogClockModeReg(self, mode=0x06e):
- self.ARMwriteMem(WD_CMR, mode)
+ self.ARMwriteMem(WD_CMR, [mode])
def setWatchDogControlReg(self, mode=0xC071):
- self.ARMwriteMem(WD_CR, mode)
+ self.ARMwriteMem(WD_CR, [mode])
def getWatchDogStatusReg(self):
- return self.ARMreadMem(WD_SR)
+ return self.ARMreadMem(WD_SR)[0]
+ def disableWatchDog(self):
+ # 0x234 in OKEY enables writing and 0 in lowest nibble disables
+ self.setWatchDogOverflowModeReg()
+ def enableWatchDog(self):
+ # Initialize the WD Clock Mode Register
+ self.setWatchDogClockModeReg(mode=0x0000373c)
+ # Restart the timer
+ self.setWatchDogControlReg(mode=0x0000c071)
+ # Enable the watchdog
+ self.setWatchDogOverflowModeReg(mode=0x00002340)
+ def statWatchDog(self):
+ print "Status Watch Dog:"
+ print "Register Value: 0b%s" % '{0:032b}'.format(self.getWatchDogOverflowModeReg()[0])
+ print self.getWatchDogOverflowModeStr()
+ print "Clock Mode Reg: %x" % self.getWatchDogClockModeReg()
+ print "Status Reg: %x" % self.getWatchDogStatusReg()
+ def checkWatchDog(self):
+ return self.getWatchDogOverflowModeStr()
+
def getChipID(self):
chipid = self.ARMreadMem(SF_CIDR,1)
for page in xrange(pagecount):
pages.append(self.ARMreadChunk(addr+(pagesz*page), pagesz))
return pages
-
+
+
+######### command line stuff #########
+
+from GoodFETARM7 import *
+
+def at91x40_main():
+ ''' this function should be called from command line app '''
+ #Initialize FET and set baud rate
+ client=GoodFETAT91X40()
+ client.serInit()
+
+ client.setup()
+ client.start()
+
+ at91x40_cli_handler(client, sys.argv)
+
+def at91x40_cli_handler(client, argv):
+
+ if(argv[1]=="chipRegStr"):
+ client.halt()
+ print "#####"
+ print client.getChipSelectRegstr(int(argv[2]))
+ print "#####"
+ client.resume()
+
+ if(argv[1]=="chipRegList"):
+ client.halt()
+ print "#####"
+ print client.getChipSelectReglist(int(argv[2]))
+ print "#####"
+ client.resume()
+
+ if(argv[1]=="chipRegValue"):
+ client.halt()
+ print "#####"
+ print "Chip Register Value:",hex(client.getChipSelectReg(int(argv[2])))
+ print "#####"
+
+ if(argv[1]=="ecdump"):
+ f = argv[2]
+ start=0x00000000
+ stop=0xFFFFFFFF
+ if(len(argv)>3):
+ start=int(argv[3],16)
+ if(len(argv)>4):
+ stop=int(argv[4],16)
+
+ ##############################3
+ # Error checking requires a special register
+ # Should an error occur while reading from the chip's memory
+ # These values will help to test if the chip is working and
+ # the memory is mapped properly before continuing
+ # Use the chipRegStr verb to determine the value of the
+ # Special Register when the chip is operating normally
+ # Example: ./goodfet.at91x40 chipRegValue 1
+ ##############################3
+ # user$ ./goodfet.at91x40 chipRegValue 1
+ # Identifying Target:
+ # # DEBUG 0x120
+ # Chip IDCODE: 0x1f0f0f0f
+ # ver: 1
+ # partno: f0f0
+ # mfgid: 787
+ #
+ # Debug Status: Interrupts Enabled (or not?)
+ #
+ # #####
+ # Chip Register Value: 0x10000000
+ # #####
+ ##############################
+ special_reg_num=1
+ special_addr=0x010000000
+ if(len(argv)>5):
+ # Yes, this requires that you set the start and stop addresses
+ special_reg_num=int(argv[5])
+ special_addr=int(argv[6],16)
+
+ print "Dumping from %04x to %04x as %s." % (start,stop,f)
+ #h = IntelHex16bit(None)
+ # FIXME: get mcu state and return it to that state
+ client.halt()
+
+ h = IntelHex(None)
+ i=start
+ while i<=stop:
+ err_cnt = 0
+ #data=client.ARMreadMem(i, 48)
+ try:
+ data=client.ARMreadChunk(i, 48, verbose=0)
+ print "Dumped %06x."%i
+ for dword in data:
+ if i<=stop and dword != 0xdeadbeef:
+ h.puts( i, struct.pack("<I", dword) )
+ err_cnt = 0
+ i+=4
+ # FIXME: get mcu state and return it to that state
+ except:
+ # Handle exceptions by counting errors after pausing to let ARM settle
+ err_cnt = 1
+ fail = 0
+ while err_cnt:
+ time.sleep(.25)
+ if err_cnt == 100:
+ print "Unknown error occurred at least 100 times. Resync did not work. Writing incomplete data to file."
+ fail = 1
+ break
+ else:
+ try:
+ print "Unknown error during read. Resync and retry."
+
+ # If we error out several times then reset the chip and restart
+ # This uses a special register value from a Chip Select Register
+ # to test that the chip is in the operation state we expect
+ if not ((err_cnt+1) % 2):
+ reset_cnt = 0
+ while True:
+ print " Reset:",reset_cnt
+ check_addr = client.getChipSelectReg(special_reg_num)
+ print " Special Addr:",hex(special_addr)
+ print " Check Addr:",hex(check_addr)
+ if (special_addr == check_addr):
+ break
+ if reset_cnt == 10:
+ reset_cnt = 0
+ print " Resetting Target"
+ client.ARMresettarget(1000)
+ client.halt()
+ reset_cnt += 1
+ time.sleep(.25)
+ else:
+ #Resync ARM and Watch Dog
+ client.resume()
+ client.halt()
+
+ #Disable Watch Dog
+ if client.checkWatchDog():
+ client.disableWatchDog()
+ err_cnt = 0
+ except:
+ err_cnt += 1
+ pass
+ if fail:
+ break
+
+ client.resume()
+ h.write_hex_file(f)
+
+
+
+ if(argv[1]=="memorymap"):
+ client.halt()
+ print client.getEBIMCR()
+ print ""
+ print client.getEBIMemoryMap()
+ client.resume()
+
+ if(argv[1]=="memorycontrolreg"):
+ client.halt()
+ print client.getEBIMCR()
+ client.resume()
+
+
+
+ if(argv[1]=="stat_watchdog"):
+ client.halt()
+ print "Watch Dog Status:"
+ print "--"
+ client.statWatchDog()
+ client.resume()
+
+ if(argv[1]=="test_disable_watchdog"):
+ client.halt()
+ print "Status Watch Dog:"
+ client.statWatchDog()
+ print "--"
+ print "Disabling Watchdog Timer:"
+ client.disableWatchDog()
+ time.sleep(2) # pause to settle
+ print "\nChecking:"
+ client.statWatchDog()
+ print "--"
+ print "Done. Resume may re-enable Watch Dog."
+ client.resume()
+
+ # anything we didn't provide from arm7:
+ arm7_cli_handler(client, argv)
+
+ #client.ARMreleasecpu()
+ #client.ARMstop()
+
+
+if __name__ == "__main__":
+ if(len(sys.argv)==1):
+ at91x40_syntax()
+
+ else:
+ at91x40_main()
+
+
import struct
import binascii
-from GoodFETARM7 import GoodFETARM
+from GoodFETARM7 import *
from intelhex import IntelHex16bit, IntelHex
+if __name__ == "__main__":
+ if(len(sys.argv)==1):
+ arm7_syntax()
-if(len(sys.argv)==1):
- print "Usage: %s verb [objects]\n" % sys.argv[0]
- # halt, resume... but need for flash and dump to leave it as it was
- print "%s info" % sys.argv[0]
- print "%s dump $foo.hex [0x$start 0x$stop]" % sys.argv[0]
- print "%s erase" % sys.argv[0]
- print "%s eraseinfo" % sys.argv[0]
- print "%s flash $foo.hex [0x$start 0x$stop]" % sys.argv[0]
- print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0]
- print "%s poke 0x$adr 0x$val" % sys.argv[0]
- print "%s peek 0x$start [0x$stop]" % sys.argv[0]
- print "%s reset" % sys.argv[0]
- sys.exit()
+ else:
+ arm7_main()
-#Initialize FET and set baud rate
-client=GoodFETARM()
-client.serInit()
-client.setup()
-client.start()
-
-if(sys.argv[1]=="info"):
- client.halt()
- client.resume()
-
-
-if(sys.argv[1]=="dump"):
- f = sys.argv[2]
- start=0x00000000
- stop=0xFFFFFFFF
- if(len(sys.argv)>3):
- start=int(sys.argv[3],16)
- if(len(sys.argv)>4):
- stop=int(sys.argv[4],16)
-
- print "Dumping from %04x to %04x as %s." % (start,stop,f)
- #h = IntelHex16bit(None)
- # FIXME: get mcu state and return it to that state
- client.halt()
-
- h = IntelHex(None)
- i=start
- while i<=stop:
- #data=client.ARMreadMem(i, 48)
- data=client.ARMreadChunk(i, 48, verbose=0)
- print "Dumped %06x."%i
- for dword in data:
- if i<=stop and dword != 0xdeadbeef:
- h.puts( i, struct.pack("<I", dword) )
- i+=4
- # FIXME: get mcu state and return it to that state
- client.resume()
- h.write_hex_file(f)
-
-'''
-if(sys.argv[1]=="erase"):
- print "Erasing main flash memory."
- client.ARMmasserase()
-
-if(sys.argv[1]=="eraseinfo"):
- print "Erasing info memory."
- client.ARMinfoerase()
-
-
-'''
-if(sys.argv[1]=="ivt"):
- client.ARMreprChunk(0xFFC0,0xFFFF)
-
-if(sys.argv[1]=="regs"):
- for i in range(0,16):
- print "r%i=%04x" % (i,client.ARMget_register(i))
-
-if(sys.argv[1]=="flash"):
- f=sys.argv[2]
- start=0
- stop=0x10000
- if(len(sys.argv)>3):
- start=int(sys.argv[3],16)
- if(len(sys.argv)>4):
- stop=int(sys.argv[4],16)
-
- client.halt()
- h = IntelHex16bit(f)
-
- #Should this be default?
- #Makes flashing multiple images inconvenient.
- #client.ARMmasserase()
-
- count=0; #Bytes in commit.
- first=0
- vals=[]
- last=0; #Last address committed.
- for i in h._buf.keys():
- if((count>0x40 or last+2!=i) and count>0 and i&1==0):
- #print "%i, %x, %x" % (len(vals), last, i)
- client.ARMpokeflashblock(first,vals)
- count=0
- first=0
- last=0
- vals=[]
- if(i>=start and i<stop and i&1==0):
- val=h[i>>1]
- if(count==0):
- first=i
- last=i
- count+=2
- vals+=[val&0xff,(val&0xff00)>>8]
- if(i%0x100==0):
- print "%04x" % i
- if count>0: #last commit, ivt
- client.ARMpokeflashblock(first,vals)
- client.resume()
-
-if(sys.argv[1]=="verify"):
- f=sys.argv[2]
- start=0
- stop=0xFFFF
- if(len(sys.argv)>3):
- start=int(sys.argv[3],16)
- if(len(sys.argv)>4):
- stop=int(sys.argv[4],16)
-
- client.halt()
- h = IntelHex16bit(f)
- for i in h._buf.keys():
- if(i>=start and i<stop and i&1==0):
- peek=client.peek(i)
- if(h[i>>1]!=peek):
- print "ERROR at %04x, found %04x not %04x"%(i,peek,h[i>>1])
- if(i%0x100==0):
- print "%04x" % i
- client.resume()
-
-
-if(sys.argv[1]=="peek"):
- start = 0x0000
- if(len(sys.argv)>2):
- start=int(sys.argv[2],16)
-
- stop = start+4
- if(len(sys.argv)>3):
- stop=int(sys.argv[3],16)
-
- print "Peeking from %04x to %04x." % (start,stop)
- client.halt()
- for dword in client.ARMreadChunk(start, (stop-start)/4, verbose=0):
- print "%.4x: %.8x" % (start, dword)
- start += 4
- client.resume()
-
-if(sys.argv[1]=="poke"):
- start=0x0000
- val=0x00
- if(len(sys.argv)>2):
- start=int(sys.argv[2],16)
- if(len(sys.argv)>3):
- val=int(sys.argv[3],16)
-
- print "Poking %06x to become %04x." % (start,val)
- client.halt()
- #???while client.ARMreadMem(start)[0]&(~val)>0:
- client.ARMwriteChunk(start, [val])
- print "Poked to %.8x" % client.ARMreadMem(start)[0]
- client.resume()
-
-
-if(sys.argv[1]=="reset"):
- #Set PC to RESET vector's value.
-
- #client.ARMsetPC(0x00000000)
- #client.ARMset_regCPSR(0)
- #client.ARMreleasecpu()
- client.ARMresettarget(1000)
-
-#client.ARMreleasecpu()
-#client.ARMstop()
--- /dev/null
+#!/usr/bin/env python
+
+import sys
+import struct
+import binascii
+import time
+
+from GoodFETAT91X40 import *
+from intelhex import IntelHex16bit, IntelHex
+
+#######################################
+# GoodFET AT91r40008
+# PIN PIN
+#
+# 1 <----- TDO ----> 90
+# 3 <----- TDI ----> 89
+# 5 <----- TMS ----> 88
+# 7 <----- TCK ----> 91
+# 9 <----- GND ----> GND
+# 11 <----- RST ----> 79
+#######################################
+
+
+def at91x40_syntax():
+ print "Usage: %s verb [objects]\n" % sys.argv[0]
+ print "%s info" % sys.argv[0]
+ print "%s dump $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s ecdump $foo.hex [0x$start 0x$stop] - exception-handling dump" % sys.argv[0]
+ print "%s erase" % sys.argv[0]
+ print "%s eraseinfo" % sys.argv[0]
+ print "%s flash $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0]
+ print "%s poke 0x$adr 0x$val" % sys.argv[0]
+ print "%s peek 0x$start [0x$stop]" % sys.argv[0]
+ print "%s stat_watchdog" % sys.argv[0]
+ print "%s test_disable_watchdog" % sys.argv[0]
+ print "%s reset" % sys.argv[0]
+ sys.exit()
+
+if __name__ == "__main__":
+ if(len(sys.argv)==1):
+ at91x40_syntax()
+
+ else:
+ at91x40_main()
+
+
print >>sys.stderr,"Starting JTAG ARM on goodfet...\n"
client.start()
print "STARTUP: %s\n"%repr(client.data)
+ client.disableWatchDog()
#
def print_registers():