2 # GoodFET Client Library
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
6 # This code is being rewritten and refactored. You've been warned!
11 from GoodFET import GoodFET;
12 from intelhex import IntelHex;
14 import xml.dom.minidom;
16 class GoodFETCC(GoodFET):
17 """A GoodFET variant for use with Chipcon 8051 Zigbee SoC."""
19 smartrfpath="/opt/smartrf7";
20 def SRF_chipdom(self,chip="cc1110", doc="register_definition.xml"):
21 fn="%s/config/xml/%s/%s" % (self.smartrfpath,chip,doc);
22 print "Opening %s" % fn;
23 return xml.dom.minidom.parse(fn)
24 def CMDrs(self,args=[]):
25 """Chip command to grab the radio state."""
26 self.SRF_radiostate();
27 def SRF_radiostate(self):
29 chip=self.CCversions.get(ident&0xFF00);
30 dom=self.SRF_chipdom(chip,"register_definition.xml");
31 for e in dom.getElementsByTagName("registerdefinition"):
32 for f in e.childNodes:
33 if f.localName=="DeviceName":
34 print "// %s RadioState" % (f.childNodes[0].nodeValue);
35 elif f.localName=="Register":
39 for g in f.childNodes:
40 if g.localName=="Name":
41 name=g.childNodes[0].nodeValue;
42 elif g.localName=="Address":
43 address=g.childNodes[0].nodeValue;
44 elif g.localName=="Description":
46 description=g.childNodes[0].nodeValue;
47 #print "SFRX(%10s, %s); /* %50s */" % (name,address, description);
48 print "%-10s=0x%02x; /* %-50s */" % (
49 name,self.CCpeekdatabyte(eval(address)), description);
52 self.writecmd(0x30,0x86,0,self.data);
53 def CCreleasecpu(self):
55 self.writecmd(0x30,0x87,0,self.data);
59 #print "Status: %s" % self.CCstatusstr();
61 #Grab ident three times, should be equal.
62 ident1=self.CCident();
63 ident2=self.CCident();
64 ident3=self.CCident();
65 if(ident1!=ident2 or ident2!=ident3):
66 print "Error, repeated ident attempts unequal."
67 print "%04x, %04x, %04x" % (ident1, ident2, ident3);
69 #Single step, printing PC.
70 print "Tracing execution at startup."
73 byte=self.CCpeekcodebyte(i);
74 #print "PC=%04x, %02x" % (pc, byte);
77 print "Verifying that debugging a NOP doesn't affect the PC."
80 self.CCdebuginstr([0x00]);
81 if(pc!=self.CCgetPC()):
82 print "ERROR: PC changed during CCdebuginstr([NOP])!";
84 print "Checking pokes to XRAM."
85 for i in range(0xf000,0xf020):
86 self.CCpokedatabyte(i,0xde);
87 if(self.CCpeekdatabyte(i)!=0xde):
88 print "Error in XDATA at 0x%04x" % i;
90 #print "Status: %s." % self.CCstatusstr();
96 """Move the FET into the CC2430/CC2530 application."""
97 #print "Initializing Chipcon.";
98 self.writecmd(0x30,0x10,0,self.data);
99 def CCrd_config(self):
100 """Read the config register of a Chipcon."""
101 self.writecmd(0x30,0x82,0,self.data);
102 return ord(self.data[0]);
103 def CCwr_config(self,config):
104 """Write the config register of a Chipcon."""
105 self.writecmd(0x30,0x81,1,[config&0xFF]);
106 def CClockchip(self):
107 """Set the flash lock bit in info mem."""
108 self.writecmd(0x30, 0x9A, 0, None);
110 """Set the flash lock bit in info mem."""
114 CCversions={0x0100:"cc1110",
119 0xA500:"cc2530", #page 52 of SWRU191
122 CCpagesizes={0x01: 1024, #"CC1110",
123 0x85: 2048, #"CC2430",
124 0x89: 2048, #"CC2431",
125 0x81: 1024, #"CC2510",
126 0x91: 1024, #"CC2511",
127 0xA5: 2048, #"CC2530", #page 52 of SWRU191
128 0xB5: 2048, #"CC2531",
129 0xFF: 0 } #"CCmissing"};
130 def infostring(self):
131 return self.CCidentstr();
132 def CCidentstr(self):
133 ident=self.CCident();
134 chip=self.CCversions.get(ident&0xFF00);
135 return "%s/r%02x" % (chip, ident&0xFF);
137 """Get a chipcon's ID."""
138 self.writecmd(0x30,0x8B,0,None);
139 chip=ord(self.data[0]);
140 rev=ord(self.data[1]);
141 return (chip<<8)+rev;
142 def CCpagesize(self):
143 """Get a chipcon's ID."""
144 self.writecmd(0x30,0x8B,0,None);
145 chip=ord(self.data[0]);
146 size=self.CCpagesizes.get(chip);
148 print "ERROR: Pagesize undefined.";
149 print "chip=%02x" %chip;
154 """Get a chipcon's PC."""
155 self.writecmd(0x30,0x83,0,None);
156 hi=ord(self.data[0]);
157 lo=ord(self.data[1]);
159 def CCcmd(self,phrase):
160 self.writecmd(0x30,0x00,len(phrase),phrase);
161 val=ord(self.data[0]);
162 print "Got %02x" % val;
164 def CCdebuginstr(self,instr):
165 self.writecmd(0x30,0x88,len(instr),instr);
166 return ord(self.data[0]);
167 def peek8(self,address, memory="code"):
168 if(memory=="code" or memory=="flash" or memory=="vn"):
169 return self.CCpeekcodebyte(address);
170 elif(memory=="data" or memory=="xdata" or memory=="ram"):
171 return self.CCpeekdatabyte(address);
172 elif(memory=="idata" or memory=="iram"):
173 return self.CCpeekirambyte(address);
174 print "%s is an unknown memory." % memory;
176 def CCpeekcodebyte(self,adr):
177 """Read the contents of code memory at an address."""
178 self.data=[adr&0xff, (adr&0xff00)>>8];
179 self.writecmd(0x30,0x90,2,self.data);
180 return ord(self.data[0]);
181 def CCpeekdatabyte(self,adr):
182 """Read the contents of data memory at an address."""
183 self.data=[adr&0xff, (adr&0xff00)>>8];
184 self.writecmd(0x30,0x91, 2, self.data);
185 return ord(self.data[0]);
186 def CCpeekirambyte(self,adr):
187 """Read the contents of IRAM at an address."""
188 self.data=[adr&0xff];
189 self.writecmd(0x30,0x02, 1, self.data);
190 return ord(self.data[0]);
191 def CCpeekiramword(self,adr):
192 """Read the little-endian contents of IRAM at an address."""
193 return self.CCpeekirambyte(adr)+(
194 self.CCpeekirambyte(adr+1)<<8);
195 def CCpokeiramword(self,adr,val):
196 self.CCpokeirambyte(adr,val&0xff);
197 self.CCpokeirambyte(adr+1,(val>>8)&0xff);
198 def CCpokeirambyte(self,adr,val):
199 """Write the contents of IRAM at an address."""
200 self.data=[adr&0xff, val&0xff];
201 self.writecmd(0x30,0x02, 2, self.data);
202 return ord(self.data[0]);
204 def CCpokedatabyte(self,adr,val):
205 """Write a byte to data memory."""
206 self.data=[adr&0xff, (adr&0xff00)>>8, val];
207 self.writecmd(0x30, 0x92, 3, self.data);
208 return ord(self.data[0]);
209 def CCchiperase(self):
210 """Erase all of the target's memory."""
211 self.writecmd(0x30,0x80,0,None);
213 """Erase all of the target's memory."""
217 """Check the status."""
218 self.writecmd(0x30,0x84,0,None);
219 return ord(self.data[0])
221 CCstatusbits={0x80 : "erase_busy",
225 0x08 : "halt_status",
230 CCconfigbits={0x20 : "soft_power_mode", #new for CC2530
233 0x02 : "timer_suspend",
234 0x01 : "sel_flash_info_page" #stricken from CC2530
238 """Check the status as a string."""
239 status=self.CCstatus();
244 str="%s %s" %(self.CCstatusbits[i],str);
248 """Start debugging."""
249 self.writecmd(0x30,0x20,0,self.data);
250 ident=self.CCidentstr();
251 #print "Target identifies as %s." % ident;
252 #print "Status: %s." % self.status();
255 #print "Status: %s." % self.status();
258 """Stop debugging."""
259 self.writecmd(0x30,0x21,0,self.data);
260 def CCstep_instr(self):
261 """Step one instruction."""
262 self.writecmd(0x30,0x89,0,self.data);
263 def CCeraseflashbuffer(self):
264 """Erase the 2kB flash buffer"""
265 self.writecmd(0x30,0x99);
266 def CCflashpage(self,adr):
267 """Flash 2kB a page of flash from 0xF000 in XDATA"""
272 print "Flashing buffer to 0x%06x" % adr;
273 self.writecmd(0x30,0x95,4,data);
275 def flash(self,file):
276 """Flash an intel hex file to code memory."""
277 print "Flashing %s" % file;
281 pagelen = self.CCpagesize(); #Varies by chip.
283 #print "page=%04x, pagelen=%04x" % (page,pagelen);
287 #Wipe the RAM buffer for the next flash page.
288 self.CCeraseflashbuffer();
289 for i in h._buf.keys():
290 while(i>=page+pagelen):
292 self.CCflashpage(page);
293 #client.CCeraseflashbuffer();
295 print "Flashed page at %06x" % page
298 #Place byte into buffer.
299 self.CCpokedatabyte(0xF000+i-page,
303 print "Buffering %04x toward %06x" % (i,page);
305 self.CCflashpage(page);
306 print "Flashed final page at %06x" % page;