#!/usr/bin/python from itertools import groupby # should be parametrized FLASH_SIZE = 32768 VECTOR_SIZE = 16 # in entries FILL_BYTE = 0xFF MAP_SIZE = 65536 def load_titxt(fin): bytes = [None] * MAP_SIZE ptr = None for line in fin: line = line.strip() if line.startswith("@"): ptr = int(line[1:], 16) elif line.startswith("q"): break else: for sb in line.split(): b = int(sb, 16) bytes[ptr] = b ptr += 1 return bytes def two_used(ar): two = [None] * ((len(ar) + 1) // 2) for i, el in enumerate(ar): if el is not None: two[i // 2] = True return two def fill_if_none(fw, i, fill_value): if fw[i] is None: fw[i] = fill_value def fill_word(fw, i, word): fw[i] = int((word >> 8) & 0xff) fw[i + 1] = int(word & 0xff) def fill_dword(fw, i, dword): fw[i] = int((dword >> 24) & 0xff) fw[i + 1] = int((dword >> 16) & 0xff) fw[i + 2] = int((dword >> 8) & 0xff) fw[i + 3] = int((dword >> 0) & 0xff) def vector_begin(vector_size): return MAP_SIZE - (vector_size * 2) def flash_begin(flash_size): return MAP_SIZE - flash_size def fill_fw(fw, flash_size, options): w = options.fill_single dw = options.fill_double invalid_vector = options.invalid_vector rb = options.repeat_bslskey if not (0 <= w < 65536): raise ValueError("invalid w %r" % w) if (dw is not None) and not (0 <= dw < 2**32): raise ValueError("invalid dw %r" % dw) if not (0 <= invalid_vector < 65536): raise ValueError("invalid invalid_vector %r" % invalid_vector) # special case for BSLSKEY vector_base = vector_begin(VECTOR_SIZE) if (rb > 0): if not (0 <= options.bslskey < 65536): raise ValueError("invalid bslskey %r" % options.bslskey) for i in xrange(vector_base - 2 * rb, vector_base, 2): fill_word(fw, i, options.bslskey) # special case for interrupt vectors for i in xrange(vector_base, MAP_SIZE, 2): if fw[i] is None: fill_word(fw, i, invalid_vector) # common cases flash_base = flash_begin(flash_size) if dw is not None: du = two_used(two_used(fw)) for i in xrange(flash_base, len(fw), 4): if not du[i // 4]: fill_dword(fw, i, dw) wu = two_used(fw) for i in xrange(flash_base, len(fw), 2): if not wu[i // 2]: fill_word(fw, i, w) for i in xrange(flash_base, len(fw)): fill_if_none(fw, i, FILL_BYTE) def chunkify(lst, n): gp = [] for el in lst: gp.append(el) if len(gp) >= n: yield gp gp = [] if gp: yield gp def save_titxt(fout, fw): for k, g in groupby(enumerate(fw), lambda (i, x): x is None): if k is False: chunk = list(g) start = chunk[0][0] data = [x for (i, x) in chunk] fout.write("@%04X\r\n" % start) for g in chunkify(data, 16): line_str = " ".join(["%02X" % e for e in g]) fout.write(line_str + "\r\n") fout.write("q\r\n") fout.close() def fill_titxt(fin, fout, options): fw = load_titxt(fin) fill_fw(fw, FLASH_SIZE, options) save_titxt(fout, fw) def main(): from optparse import OptionParser import sys parser = OptionParser(usage="fill_titxt -o output.txt input.txt") parser.add_option("-d", "--fill-double-word", dest="fill_double", type="long", help="fill aligned double words with") parser.add_option("-w", "--fill-single-word", dest="fill_single", type="int", help="fill single words with") parser.add_option("-x", "--bslskey", dest="bslskey", default=0, type="int", action="store", help="fill skey with") parser.add_option("-n", "--repeat-bslskey", dest="repeat_bslskey", default=0, type="int", action="store", help="use n words ending at bslskey") parser.add_option("-i", "--invalid-vector", dest="invalid_vector", type="int", default=0, help="address of invalid " \ "interrupt handler") parser.add_option("-o", "--output", dest="output", help="output file") (options, args) = parser.parse_args() if (len(args) != 1) \ or (not options.output) \ or (options.fill_single is None): parser.print_help() sys.exit(1) if (options.fill_single is None) or not (0 <= options.fill_single < 65536): print >> sys.stderr, "-w should verify 0 <= n < 65536" if (options.fill_double is not None) \ and not (0 <= options.fill_double < 2**32): print >> sys.stderr, "-d should verify 0 <= n < 2**32" if not (0 <= options.invalid_vector < 65536): print >> sys.stderr, "-i should verify 0 <= n < 65536" if not (0 <= options.bslskey < 65536): print >> sys.stderr, "-x should verify 0 <= n < 65536" if not (0 <= options.repeat_bslskey <= 16): print >> sys.stderr, "-n should verify 0 <= n <= 16" fin = open(args[0], "rU") fout = open(options.output, "wb") fill_titxt(fin, fout, options) if __name__ == '__main__': main()