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 Exception("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 Exception("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 Exception("Bad line start character")
66 hex = line[1:].replace("\r\n", "")
67 data = hex.decode("hex")
73 raise Exception("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:
80 raise Exception("Gap in file")
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
96 print "Addr (rest) 0x%x" % buf_addr
97 diff = self.pagesize-len(buf)
98 buf+=chr(0xff)*diff # fill with 0xff
99 handle(buf_addr, buf[:self.pagesize])
100 if lFirstRow: # was first
101 buf_addr = lFirstRow[0]
103 print "Addr (First) 0x%x" % buf_addr
104 handle(buf_addr, buf)
106 raise Exception("Unknown type %d" % typ)
109 print "Byte count:", count
112 def jump(self, addr):
113 self.run_cmd(CMD_JUMP)
123 def load(self, filename):
131 self.program(filename)
132 print "Time: %.1fs" % (time() - t1)
135 self.compare(filename)
136 print "Time: %.1fs" % (time() - t1)
139 dev = i2c(self.i2c_addr)
144 dev = i2c(self.i2c_addr)
149 def run_cmd(self, cmd, addr=0x0, num=0, data=""):
151 s1 = struct.pack("<BLB%ds" % (length), cmd, addr, num, data)
153 s2 = struct.pack("B", 0xff)
157 self.run_cmd(CMD_INFO)
159 return s == "Bootloader"
161 def get_pagesize(self):
162 self.run_cmd(CMD_PAGESIZE)
165 if i not in [64, 128]:
166 raise Exception("Unsupported pagesize")
170 def to_bootloader(addr):
172 s = struct.pack("BB", 0xff, 0xa5)
177 if __name__ == "__main__":
178 usage = "usage: %prog [options] addr [ihex]"
179 parser = OptionParser(usage=usage)
180 parser.add_option("-b", "--start-bootloader", action="store_true", dest="bToBoot", default=False, help="Start Bootloader")
181 parser.add_option("-j", "--jump", action="store_true", dest="bJump", default=False, help="Jump to Program")
183 (options, args) = parser.parse_args()
185 print "Missing Address"
187 addr = int(args[0], 16)
191 loader = bootloader(addr)
195 print "Jump to Program"