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 diff = self.pagesize-len(buf)
96 buf+=chr(0xff)*diff # fill with 0xff
97 handle(buf_addr, buf[:self.pagesize])
98 if lFirstRow: # was first
99 buf_addr = lFirstRow[0]
101 print "Addr (First) 0x%x" % buf_addr
102 handle(buf_addr, buf)
104 raise("Unknown type %d" % typ)
107 print "Byte count:", count
110 def jump(self, addr):
111 self.run_cmd(CMD_JUMP)
121 def load(self, filename):
129 self.program(filename)
130 print "Time: %.1fs" % (time() - t1)
133 self.compare(filename)
134 print "Time: %.1fs" % (time() - t1)
137 dev = i2c(self.i2c_addr)
142 dev = i2c(self.i2c_addr)
147 def run_cmd(self, cmd, addr=0x0, num=0, data=""):
149 s1 = struct.pack("<BLB%ds" % (length), cmd, addr, num, data)
151 s2 = struct.pack("B", 0xff)
155 self.run_cmd(CMD_INFO)
157 return s == "Bootloader"
159 def get_pagesize(self):
160 self.run_cmd(CMD_PAGESIZE)
163 if i not in [64, 128]:
168 def to_bootloader(addr):
170 s = struct.pack("BB", 0xff, 0xa5)
175 if __name__ == "__main__":
176 usage = "usage: %prog [options] addr [ihex]"
177 parser = OptionParser(usage=usage)
178 parser.add_option("-b", "--start-bootloader", action="store_true", dest="bToBoot", default=False, help="Start Bootloader")
179 parser.add_option("-j", "--jump", action="store_true", dest="bJump", default=False, help="Jump to Program")
181 (options, args) = parser.parse_args()
183 print "Missing Address"
185 addr = int(args[0], 16)
189 loader = bootloader(addr)
193 print "Jump to Program"