2 # GoodFET Client Library
5 # Good luck with alpha / beta code.
6 # Contributions and bug reports welcome.
9 import sys, binascii, struct
24 # ARM7TDMI JTAG commands
30 GET_DEBUG_STATE = 0x85
42 READ_CODE_MEMORY = 0x91 # ??
43 WRITE_FLASH_PAGE = 0x92 # ??
44 READ_FLASH_PAGE = 0x93 # ??
45 MASS_ERASE_FLASH = 0x94 # ??
48 CHIP_ERASE = 0x97 # can do?
49 # Really ARM specific stuff
57 from GoodFET import GoodFET
58 from intelhex import IntelHex
63 class GoodFETARM(GoodFET):
64 """A GoodFET variant for use with ARM7TDMI microprocessor."""
67 self.writecmd(0x33,HALTCPU,0,self.data)
68 def ARMreleasecpu(self):
70 self.writecmd(0x33,RESUMECPU,0,self.data)
71 def ARMsetModeArm(self):
72 self.writecmd(0x33,SET_MODE_ARM,0,self.data)
76 #print "Status: %s" % self.ARMstatusstr()
78 #Grab ident three times, should be equal.
79 ident1=self.ARMident()
80 ident2=self.ARMident()
81 ident3=self.ARMident()
82 if(ident1!=ident2 or ident2!=ident3):
83 print "Error, repeated ident attempts unequal."
84 print "%04x, %04x, %04x" % (ident1, ident2, ident3)
86 #Single step, printing PC.
87 print "Tracing execution at startup."
90 byte=self.ARMpeekcodebyte(i)
91 #print "PC=%04x, %02x" % (pc, byte)
94 print "Verifying that debugging a NOP doesn't affect the PC."
97 self.ARMdebuginstr([NOP])
98 if(pc!=self.ARMgetPC()):
99 print "ERROR: PC changed during ARMdebuginstr([NOP])!"
101 print "Checking pokes to XRAM."
102 for i in range(0xf000,0xf020):
103 self.ARMpokedatabyte(i,0xde)
104 if(self.ARMpeekdatabyte(i)!=0xde):
105 print "Error in DATA at 0x%04x" % i
107 #print "Status: %s." % self.ARMstatusstr()
113 """Move the FET into the JTAG ARM application."""
114 #print "Initializing ARM."
115 self.writecmd(0x33,SETUP,0,self.data)
116 def ARMget_dbgstate(self):
117 """Read the config register of an ARM."""
118 self.writecmd(0x33,GET_DEBUG_STATE,0,self.data)
119 print "DEBUGGING get_dbgstate: %s"%repr(self.data)
120 retval = struct.unpack("<L", self.data[:4])[0]
122 def ARMget_dbgctrl(self):
123 """Read the config register of an ARM."""
124 self.writecmd(0x33,GET_DEBUG_CTRL,0,self.data)
125 retval = struct.unpack("B", self.data)[0]
127 def ARMset_dbgctrl(self,config):
128 """Write the config register of an ARM."""
129 self.writecmd(0x33,SET_DEBUG_CTRL,1,[config&7])
130 def ARMlockchip(self):
131 """Set the flash lock bit in info mem."""
132 self.writecmd(0x33, LOCKCHIP, 0, [])
135 def ARMidentstr(self):
136 ident=self.ARMident()
138 partno = (ident >> 12) & 0x10
139 mfgid = ident & 0xfff
140 return "mfg: %x\npartno: %x\nver: %x\n(%x)" % (ver, partno, mfgid, ident);
142 """Get an ARM's ID."""
143 self.writecmd(0x33,GET_CHIP_ID,0,[])
144 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
147 """Get an ARM's PC."""
148 self.writecmd(0x33,GET_PC,0,[])
149 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
151 def ARMget_register(self, reg):
152 """Get an ARM's Register"""
153 self.writecmd(0x33,GET_REGISTER,1,[reg&0xff])
154 print "DEBUG:GET_REGISTER: %s"%repr(self.data)
155 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
157 def ARMset_register(self, reg, val):
158 """Get an ARM's Register"""
159 self.writecmd(0x33,GET_REGISTER,8,[reg,0,0,0,val>>24, (val>>16)&0xff, (val>>8)&0xff, val&0xff])
160 print "DEBUG:SET_REGISTER: %s"%repr(self.data)
161 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
163 def ARMget_registers(self):
164 """Get an ARM's Register"""
165 self.writecmd(0x33,GET_REGISTERS,0,[])
166 print "DEBUG:GET_REGISTER: %s"%repr(self.data)
167 #retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
169 def ARMset_registers(self, regs):
170 """Get an ARM's Register"""
173 regarray.merge([reg>>24, (reg>>16)&0xff, (reg>>8)&0xff, reg&0xff])
174 self.writecmd(0x33,GET_REGISTER,16*4,regarray)
175 print "DEBUG:SET_REGISTER: %s"%repr(self.data)
176 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
178 def ARMcmd(self,phrase):
179 self.writecmd(0x33,READ,len(phrase),phrase)
180 val=ord(self.data[0])
181 print "Got %02x" % val
183 def ARMdebuginstr(self,instr):
184 if type (instr) == int:
185 instr = struct.pack("<L", instr)
186 self.writecmd(0x33,DEBUG_INSTR,len(instr),instr)
187 return (self.data[0])
188 def ARMpeekcodebyte(self,adr):
189 """Read the contents of code memory at an address."""
190 self.data=[adr&0xff, (adr&0xff00)>>8]
191 self.writecmd(0x33,PEEK,2,self.data)
192 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
194 def ARMpeekdatabyte(self,adr):
195 """Read the contents of data memory at an address."""
196 self.data=[adr&0xff, (adr&0xff00)>>8]
197 self.writecmd(0x33, PEEK, 2, self.data)
198 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
200 def ARMpokedatabyte(self,adr,val):
201 """Write a byte to data memory."""
202 self.data=[adr&0xff, (adr&0xff00)>>8, val]
203 self.writecmd(0x33, POKE, 3, self.data)
204 retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
206 def ARMchiperase(self):
207 """Erase all of the target's memory."""
208 self.writecmd(0x33,CHIP_ERASE,0,[])
210 """Check the status."""
211 self.writecmd(0x33,GET_DEBUG_STATE,0,[])
212 return ord(self.data[0])
216 0x04 : "Interrupts Enabled (or not?)",
221 0x04 : "disable interrupts",
222 0x02 : "force dbgrq",
223 0x01 : "force dbgack"
226 def ARMstatusstr(self):
227 """Check the status as a string."""
228 status=self.ARMstatus()
233 str="%s %s" %(self.ARMstatusbits[i],str)
237 """Start debugging."""
238 self.writecmd(0x33,START,0,self.data)
239 #ident=self.ARMidentstr()
240 #print "Target identifies as %s." % ident
241 #print "Status: %s." % self.ARMstatusstr()
242 #self.ARMreleasecpu()
244 #print "Status: %s." % self.ARMstatusstr()
247 """Stop debugging."""
248 self.writecmd(0x33,STOP,0,self.data)
249 def ARMstep_instr(self):
250 """Step one instruction."""
251 self.writecmd(0x33,STEP_INSTR,0,self.data)
252 def ARMflashpage(self,adr):
253 """Flash 2kB a page of flash from 0xF000 in XDATA"""
258 print "Flashing buffer to 0x%06x" % adr
259 self.writecmd(0x33,MASS_FLASH_PAGE,4,data)
261 def writecmd(self, app, verb, count=0, data=[]):
262 """Write a command and some data to the GoodFET."""
263 self.serialport.write(chr(app))
264 self.serialport.write(chr(verb))
267 # count=len(data); #Initial count ignored.
269 #print "TX %02x %02x %04x" % (app,verb,count)
271 #little endian 16-bit length
272 self.serialport.write(chr(count&0xFF))
273 self.serialport.write(chr(count>>8))
275 #print "count=%02x, len(data)=%04x" % (count,len(data))
278 if(isinstance(data,list)):
279 for i in range(0,count):
280 #print "Converting %02x at %i" % (data[i],i)
284 self.serialport.write(outstr)
285 if not self.besilent: