2 # -*- coding: iso-8859-15 -*-
7 from optparse import OptionParser
8 from time import sleep, time
20 def __init__(self, addr):
24 if not self.identify():
25 raise "Bootloader not running"
26 self.pagesize = self.get_pagesize()
28 def read_mem(self, addr, num):
29 self.run_cmd(CMD_READ, addr, num)
32 def erase(self, addr):
33 self.run_cmd(CMD_ERASE)
36 self.run_cmd(CMD_ERASE_ALL)
38 def __compare_memarea(self, addr, data):
39 mem_cmp = self.read_mem(addr, self.pagesize)
41 print "Expected:", data.encode("hex")
42 print "Got: ", mem_cmp.encode("hex")
43 raise("Compare mismatch at 0x%x" % addr)
46 def __program_memarea(self, addr, data):
47 self.run_cmd(CMD_WRITE, addr, self.pagesize, data)
50 def compare(self, filename):
51 return self.__process_hex(filename, self.__compare_memarea)
53 def program(self, filename):
54 return self.__process_hex(filename, self.__program_memarea)
56 def __process_hex(self, filename, handle):
61 f = open(filename, "r")
65 raise("Bad line start character")
66 hex = line[1:].replace("\r\n", "")
67 data = hex.decode("hex")
73 raise("Checksum error")
74 addr, typ, data, chksum = struct.unpack(">HB%ssB" % num, data[1:])
76 if typ == 0: # Data Record
78 if next_addr is not None:
81 buf_addr = addr-len(buf)
83 if len(buf) >= self.pagesize:
85 # do the first as last one
86 lFirstRow = (buf_addr, buf[:self.pagesize])
88 print "Addr 0x%x" % buf_addr
89 handle(buf_addr, buf[:self.pagesize])
90 buf = buf[self.pagesize:]
91 elif typ == 3: # Start Segment Address Record
92 self.boot_addr = int(data.encode("hex"), 16)
93 elif typ == 1: # End of File Record
94 print "Addr (rest) 0x%x" % buf_addr
95 buf_addr+=self.pagesize
96 diff = self.pagesize-len(buf)
97 buf+=chr(0xff)*diff # fill with 0xff
98 handle(buf_addr, buf[:self.pagesize])
99 if lFirstRow: # was first
100 buf_addr = lFirstRow[0]
102 print "Addr (First) 0x%x" % buf_addr
103 handle(buf_addr, buf)
105 raise("Unknown type %d" % typ)
108 print "Byte count:", count
111 def jump(self, addr):
112 self.run_cmd(CMD_JUMP)
122 def load(self, filename):
130 self.program(filename)
131 print "Time: %.1fs" % (time() - t1)
134 self.compare(filename)
135 print "Time: %.1fs" % (time() - t1)
137 self.jump(self.boot_addr)
140 dev = i2c(self.i2c_addr)
145 dev = i2c(self.i2c_addr)
150 def run_cmd(self, cmd, addr=0x0, num=0, data=""):
152 s1 = struct.pack("<BLB%ds" % (length), cmd, addr, num, data)
154 s2 = struct.pack("B", 0xff)
158 self.run_cmd(CMD_INFO)
160 return s == "Bootloader"
162 def get_pagesize(self):
163 self.run_cmd(CMD_PAGESIZE)
166 if i not in [64, 128]:
171 def to_bootloader(addr):
173 s = struct.pack("BB", 0xff, 0xa5)
178 if __name__ == "__main__":
179 usage = "usage: %prog [options] addr [ihex]"
180 parser = OptionParser(usage=usage)
181 parser.add_option("-b", "--start-bootloader", action="store_true", dest="bToBoot", default=False, help="Start Bootloader")
183 (options, args) = parser.parse_args()
185 addr = int(args[0], 16)
189 loader = bootloader(addr)