2 # -*- coding: iso-8859-15 -*-
7 from optparse import OptionParser
8 from time import sleep, time
21 def __init__(self, addr):
25 if not self.identify():
26 raise Exception("Bootloader not running")
27 self.pagesize = self.get_pagesize()
29 def read_mem(self, addr, num):
30 self.run_cmd(CMD_READ, addr, num)
33 def erase(self, addr):
34 self.run_cmd(CMD_ERASE)
37 self.run_cmd(CMD_ERASE_ALL)
39 def __compare_memarea(self, addr, data):
40 mem_cmp = self.read_mem(addr, self.pagesize)
42 print "Expected:", data.encode("hex")
43 print "Got: ", mem_cmp.encode("hex")
44 raise Exception("Compare mismatch at 0x%x" % addr)
47 def __program_memarea(self, addr, data):
48 self.run_cmd(CMD_WRITE, addr, self.pagesize, data)
51 def compare(self, filename):
52 return self.__process_hex(filename, self.__compare_memarea)
54 def program(self, filename):
55 return self.__process_hex(filename, self.__program_memarea)
57 def __process_hex(self, filename, handle):
62 f = open(filename, "r")
66 raise Exception("Bad line start character")
67 hex = line[1:].replace("\r\n", "")
68 data = hex.decode("hex")
74 raise Exception("Checksum error")
75 addr, typ, data, chksum = struct.unpack(">HB%ssB" % num, data[1:])
77 if typ == 0: # Data Record
79 if next_addr is not None:
81 raise Exception("Gap in file")
82 buf_addr = addr-len(buf)
84 if len(buf) >= self.pagesize:
86 # do the first as last one
87 lFirstRow = (buf_addr, buf[:self.pagesize])
89 print "Addr 0x%x" % buf_addr
90 handle(buf_addr, buf[:self.pagesize])
91 buf_addr += self.pagesize
92 buf = buf[self.pagesize:]
93 elif typ == 3: # Start Segment Address Record
94 self.boot_addr = int(data.encode("hex"), 16)
95 elif typ == 1: # End of File Record
98 print "Addr (rest) 0x%x" % buf_addr
99 diff = self.pagesize-len(buf)
100 buf+=chr(0xff)*diff # fill with 0xff
101 handle(buf_addr, buf[:self.pagesize])
102 if lFirstRow: # was first
103 buf_addr = lFirstRow[0]
105 print "Addr (First) 0x%x" % buf_addr
106 handle(buf_addr, buf)
108 raise Exception("Unknown type %d" % typ)
111 print "Byte count:", count
114 def jump(self, addr):
115 self.run_cmd(CMD_JUMP)
125 def load(self, filename):
133 self.program(filename)
134 print "Time: %.1fs" % (time() - t1)
137 self.compare(filename)
138 print "Time: %.1fs" % (time() - t1)
141 dev = i2c(self.i2c_addr)
146 dev = i2c(self.i2c_addr)
151 def run_cmd(self, cmd, addr=0x0, num=0, data=""):
153 s1 = struct.pack("<BLB%ds" % (length), cmd, addr, num, data)
155 s2 = struct.pack("B", 0xff)
159 self.run_cmd(CMD_INFO)
161 return s == "Bootloader"
163 def get_pagesize(self):
164 self.run_cmd(CMD_PAGESIZE)
167 if i not in [64, 128]:
168 raise Exception("Unsupported pagesize")
171 def set_i2c_addr(self, addr):
172 self.run_cmd(CMD_I2C_ADDR, addr)
175 def to_bootloader(addr):
177 s = struct.pack("BB", 0xff, 0xa5)
182 if __name__ == "__main__":
183 usage = "usage: %prog [options] addr [ihex]"
184 parser = OptionParser(usage=usage)
185 parser.add_option("-b", "--start-bootloader", action="store_true", dest="bToBoot", default=False, help="Start Bootloader")
186 parser.add_option("-j", "--jump", action="store_true", dest="bJump", default=False, help="Jump to Program")
187 parser.add_option("-s", "--set-i2c-addr", dest="i2c_addr", type="int", help="Set I2C address")
189 (options, args) = parser.parse_args()
191 print "Missing Address"
193 addr = int(args[0], 16)
197 loader = bootloader(addr)
198 if options.i2c_addr is not None:
199 print "Setting i2c address to 0x%X" % (options.i2c_addr)
200 loader.set_i2c_addr(options.i2c_addr)
204 print "Jump to Program"