3 # A simple python client to speak to the donbL AVR boot loader
4 # donb (donb@capitolhillconsultants.com)
8 from intelhex import IntelHex
34 s.write(chr((l>>8)&0xff))
44 return "BL_ERR_INVALID"
46 return "BL_ERR_CHECKSUM"
60 x = ((ord(x) << 8) | ord(y))
63 print "getheader: BL_ERR_OK not found: ", errname(e)
73 z.append(ord(s.read()))
82 # address is always in hex
84 x = string.atol(x, 16)
86 s.write(chr((x >> 24)&0xff))
87 s.write(chr((x >> 16)&0xff))
88 s.write(chr((x >> 8)&0xff))
89 s.write(chr((x >> 0)&0xff))
91 #print "addr: sending %x" % x
95 print "error: address setting failed"
99 #print "address received: %.02x%.02x%.02x%.02x" % (x[0], x[1], x[2], x[3])
104 # peek a word at an address
113 print "peek failed: message count incorrect"
117 x = ((x[0] << 8)|x[1])
118 print "peek %s: %.04x" % (a, x)
131 print "pagesz failed: message count incorrect"
135 x = ((x[0] << 8) | x[1])
136 print "pagesz: %x" % x
141 # get the signature bytes and calibration byte
148 print "error: signature header size invalid"
154 print "signature: %.02x %.02x %.02x" % (x[0], x[1], x[2])
155 print "rc calibration: %.02x" % (x[3])
166 print "fuse failed: message count incorrect"
170 print "fuse: %.02x %.02x %.02x %.02x" % (x[0], x[1], x[2], x[3])
174 # exit the BLS command loop
180 print "error: exit attempt failed"
190 # make sure that RST is tied to RESET on the AVR so we can force BLS to execute by driving RST low
191 s = serial.Serial(p, b, timeout=TIMEOUT, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, rtscts=0)
200 # based on a (presumed) bug in the AVR architecture, the BL wont
201 # accept USART input unless it first outputs a byte. Not sure why
202 # this occurs, but here is the compensating code:
205 print "error: no paramedics available"
208 print "error: unexpected value: '+' != %.02x" % (ord(x))
211 print "boot loader found. entering command mode."
216 # upload to bootloader
219 # send the address first
221 print "error: couldnt set page address"
224 sendheader(4, len(d))
232 # twos complement the sum
233 v = (0x100 - v) & 0xff
237 print "error: flash failed"
242 print "error: checksums dont match: got=%.02x, expected=%.02x" % (x[0], v)
247 # flash an image to the chip
252 # make sure we have the page size first
255 # ingest the ihex file
258 sys.stdout.write("flashing pages: ")
260 # always start with page zero; the code will auto-jump to
261 # the new address if there is no page zero in the hexfile
265 for a in h.addresses():
266 # if the page has changed, upload
267 if (a & ~((psize)-1)) != p:
268 # upload only if we have data
270 if upload(p, d) != 1:
271 print "error: upload failed"
273 sys.stdout.write(".")
276 p = (a & ~((psize)-1))
278 # start a new list with this address
281 # reset the previous pointer
284 # insert the data at the page address
287 # if this address isn't an increment above last, fill the void
292 # ensure n reflects this byte
295 # insert the actual data byte
296 d.insert(t, ord(h.gets(a, 1)))
298 # if iterating through addresses() has completed but we still have data,
301 if upload(p, d) != 1:
302 print "error: upload failed"
304 sys.stdout.write(".")
310 # flash an image from the web
316 if getsignature() != 1:
317 print "error: can't retrieve chip signature"
320 fn="/tmp/.goodfet.hex"
321 print "fromweb: retrieving image for chip %.02x.%.02x.%.02x" % (signature[0], signature[1], signature[2])
322 os.system("curl http://pa-ri.sc/goodfet/fw/%.02x%.02x%.02x.hex > %s" % (signature[0], signature[1], signature[2], fn))
330 if len(sys.argv) > 1:
332 if len(sys.argv) > 2:
335 if blsinit(p, b) != 1:
336 print "error: couldnt initialize bls"
340 sys.stdout.write("donbL> ")
342 c = sys.stdin.readline().rstrip()
343 c = re.split("[ \t]", c)
346 print "donbL: exiting"
352 print "donbL: peeking address"
355 if c[0] == "address":
356 print "donbL: setting flash address"
360 print "donbL: retrieving page size"
363 if c[0] == "signature":
364 print "donbL: retrieving avr signature"
368 print "donbL: retrieving avr fuse and lock bytes"
372 print "donbL: flashing image"
375 if c[0] == "fromweb":
376 print "donbL: flashing new image from web"