2 # GoodFET Client Library
5 # Good luck with alpha / beta code.
6 # Contributions and bug reports welcome.
9 import sys, binascii, struct
10 import atlasutils.smartprint as asp
25 # ARM7TDMI JTAG commands
31 GET_DEBUG_STATE = 0x85
43 READ_CODE_MEMORY = 0x91 # ??
44 WRITE_FLASH_PAGE = 0x92 # ??
45 READ_FLASH_PAGE = 0x93 # ??
46 MASS_ERASE_FLASH = 0x94 # ??
49 CHIP_ERASE = 0x97 # can do?
50 # Really ARM specific stuff
58 from GoodFET import GoodFET
59 from intelhex import IntelHex
64 class GoodFETARM(GoodFET):
65 """A GoodFET variant for use with ARM7TDMI microprocessor."""
68 self.writecmd(0x33,HALTCPU,0,self.data)
69 def ARMreleasecpu(self):
71 self.writecmd(0x33,RESUMECPU,0,self.data)
72 def ARMsetModeArm(self):
73 self.writecmd(0x33,SET_MODE_ARM,0,self.data)
77 print "Status: %s" % self.ARMstatusstr()
79 #Grab ident three times, should be equal.
80 ident1=self.ARMident()
81 ident2=self.ARMident()
82 ident3=self.ARMident()
83 if(ident1!=ident2 or ident2!=ident3):
84 print "Error, repeated ident attempts unequal."
85 print "%04x, %04x, %04x" % (ident1, ident2, ident3)
87 #Set and Check Registers
88 regs = [1024+x for x in range(1,15)]
90 for x in range(len(regs)):
91 self.ARMset_register(x, regs[x])
93 for x in range(len(regs)):
94 regr.append(self.ARMget_register(x))
96 for x in range(len(regs)):
97 if regs[x] != regr[x]:
98 print "Error, R%d fail: %x != %x"%(x,regs[x],regr[x])
105 #Single step, printing PC.
106 print "Tracing execution at startup."
109 byte=self.ARMpeekcodebyte(i)
110 #print "PC=%04x, %02x" % (pc, byte)
113 print "Verifying that debugging a NOP doesn't affect the PC."
114 for i in range(1,15):
116 self.ARMdebuginstr([NOP])
117 if(pc!=self.ARMgetPC()):
118 print "ERROR: PC changed during ARMdebuginstr([NOP])!"
120 print "Checking pokes to XRAM."
121 for i in range(0xf000,0xf020):
122 self.ARMpokedatabyte(i,0xde)
123 if(self.ARMpeekdatabyte(i)!=0xde):
124 print "Error in DATA at 0x%04x" % i
126 #print "Status: %s." % self.ARMstatusstr()
132 """Move the FET into the JTAG ARM application."""
133 #print "Initializing ARM."
134 self.writecmd(0x33,SETUP,0,self.data)
135 def ARMget_dbgstate(self):
136 """Read the config register of an ARM."""
137 retval = struct.unpack("<L", self.data[:4])[0]
139 def ARMget_dbgctrl(self):
140 """Read the config register of an ARM."""
141 self.writecmd(0x33,GET_DEBUG_CTRL,0,self.data)
142 retval = struct.unpack("B", self.data)[0]
144 def ARMset_dbgctrl(self,config):
145 """Write the config register of an ARM."""
146 self.writecmd(0x33,SET_DEBUG_CTRL,1,[config&7])
147 def ARMlockchip(self):
148 """Set the flash lock bit in info mem."""
149 self.writecmd(0x33, LOCKCHIP, 0, [])
152 def ARMidentstr(self):
153 ident=self.ARMident()
155 partno = (ident >> 12) & 0x10
156 mfgid = ident & 0xfff
157 return "mfg: %x\npartno: %x\nver: %x\n(%x)" % (ver, partno, mfgid, ident);
159 """Get an ARM's ID."""
160 self.writecmd(0x33,GET_CHIP_ID,0,[])
161 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
164 """Get an ARM's PC."""
165 self.writecmd(0x33,GET_PC,0,[])
166 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
168 def ARMget_register(self, reg):
169 """Get an ARM's Register"""
170 self.writecmd(0x33,GET_REGISTER,1,[reg&0xff])
171 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
173 def ARMset_register(self, reg, val):
174 """Get an ARM's Register"""
175 self.writecmd(0x33,SET_REGISTER,8,[reg,0,0,0,val&0xff, (val>>8)&0xff, (val>>16)&0xff, val>>24])
176 #self.writecmd(0x33,SET_REGISTER,8,[reg,0,0,0, (val>>16)&0xff, val>>24, val&0xff, (val>>8)&0xff])
177 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
179 def ARMget_registers(self):
180 """Get ARM Registers"""
181 self.writecmd(0x33,GET_REGISTERS,0, [])
183 for x in range(0,len(self.data), 4):
184 retval.append(struct.unpack("<L", self.data[x:x+4])[0])
186 def ARMset_registers(self, regs):
187 """Set ARM Registers"""
190 regarry.extend([reg&0xff, (reg>>8)&0xff, (reg>>16)&0xff, reg>>24])
191 self.writecmd(0x33,SET_REGISTERS,16*4,regarry)
192 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
194 def ARMcmd(self,phrase):
195 self.writecmd(0x33,READ,len(phrase),phrase)
196 val=ord(self.data[0])
197 print "Got %02x" % val
199 def ARMdebuginstr(self,instr):
200 if type (instr) == int:
201 instr = struct.pack("<L", instr)
202 self.writecmd(0x33,DEBUG_INSTR,len(instr),instr)
203 return (self.data[0])
204 def ARMpeekcodebyte(self,adr):
205 """Read the contents of code memory at an address."""
206 self.data=[adr&0xff, (adr&0xff00)>>8]
207 self.writecmd(0x33,PEEK,2,self.data)
208 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
210 def ARMpeekdatabyte(self,adr):
211 """Read the contents of data memory at an address."""
212 self.data=[adr&0xff, (adr&0xff00)>>8]
213 self.writecmd(0x33, PEEK, 2, self.data)
214 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
216 def ARMpokedatabyte(self,adr,val):
217 """Write a byte to data memory."""
218 self.data=[adr&0xff, (adr&0xff00)>>8, val]
219 self.writecmd(0x33, POKE, 3, self.data)
220 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
222 def ARMchiperase(self):
223 """Erase all of the target's memory."""
224 self.writecmd(0x33,CHIP_ERASE,0,[])
226 """Check the status."""
227 self.writecmd(0x33,GET_DEBUG_STATE,0,[])
228 return ord(self.data[0])
232 0x04 : "Interrupts Enabled (or not?)",
237 0x04 : "disable interrupts",
238 0x02 : "force dbgrq",
239 0x01 : "force dbgack"
242 def ARMstatusstr(self):
243 """Check the status as a string."""
244 status=self.ARMstatus()
249 str="%s %s" %(self.ARMstatusbits[i],str)
253 """Start debugging."""
254 self.writecmd(0x33,START,0,self.data)
255 #ident=self.ARMidentstr()
256 #print "Target identifies as %s." % ident
257 #print "Status: %s." % self.ARMstatusstr()
258 #self.ARMreleasecpu()
260 #print "Status: %s." % self.ARMstatusstr()
263 """Stop debugging."""
264 self.writecmd(0x33,STOP,0,self.data)
265 def ARMstep_instr(self):
266 """Step one instruction."""
267 self.writecmd(0x33,STEP_INSTR,0,self.data)
268 def ARMflashpage(self,adr):
269 """Flash 2kB a page of flash from 0xF000 in XDATA"""
274 print "Flashing buffer to 0x%06x" % adr
275 self.writecmd(0x33,MASS_FLASH_PAGE,4,data)
277 def writecmd(self, app, verb, count=0, data=[]):
278 """Write a command and some data to the GoodFET."""
279 self.serialport.write(chr(app))
280 self.serialport.write(chr(verb))
283 # count=len(data); #Initial count ignored.
285 #print "TX %02x %02x %04x" % (app,verb,count)
287 #little endian 16-bit length
288 self.serialport.write(chr(count&0xFF))
289 self.serialport.write(chr(count>>8))
291 #print "count=%02x, len(data)=%04x" % (count,len(data))
294 if(isinstance(data,list)):
295 for i in range(0,count):
296 #print "Converting %02x at %i" % (data[i],i)
300 self.serialport.write(outstr)
301 if not self.besilent: