Cast to WORD (not sure it's necessary) and put braces around the arguments.
[fx2lib.git] / utils / ihx2iic.py
blob3b62f67540e1dc28d2b5defa8fc6b70534869efe
1 #!/usr/bin/env python
3 # Copyright 2009, Ubixum, Inc
5 # This file copied and modified for fx2lib from the GnuRadio project
7 # Copyright 2004,2006 Free Software Foundation, Inc.
8 #
9 # This file is part of GNU Radio
11 # GNU Radio is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 3, or (at your option)
14 # any later version.
16 # GNU Radio is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with GNU Radio; see the file COPYING. If not, write to
23 # the Free Software Foundation, Inc., 51 Franklin Street,
24 # Boston, MA 02110-1301, USA.
27 import re
28 import sys, struct
29 import os, os.path
30 from optparse import OptionParser
33 def hex_to_bytes (s):
34 if len (s) & 0x1:
35 raise ValueError, "Length must be even"
36 r = []
37 for i in range (0, len(s), 2):
38 r.append (int (s[i:i+2], 16))
39 return r
41 def msb (x):
42 return (x >> 8) & 0xff
44 def lsb (x):
45 return x & 0xff
47 class ihx_rec (object):
48 def __init__ (self, addr, type, data):
49 self.addr = addr
50 self.type = type
51 self.data = data
53 class ihx_file (object):
54 def __init__ (self):
55 self.pat = re.compile (r':[0-9A-F]{10,}')
56 def read (self, file):
57 r = []
58 for line in file:
59 line = line.strip().upper ()
60 if not self.pat.match (line):
61 raise ValueError, "Invalid hex record format"
62 bytes = hex_to_bytes (line[1:])
63 sum = reduce (lambda x, y: x + y, bytes, 0) % 256
64 if sum != 0:
65 raise ValueError, "Bad hex checksum"
66 lenx = bytes[0]
67 addr = (bytes[1] << 8) + bytes[2]
68 type = bytes[3]
69 data = bytes[4:-1]
70 if lenx != len (data):
71 raise ValueError, "Invalid hex record (bad length)"
72 if type != 0:
73 break;
74 r.append (ihx_rec (addr, type, data))
76 return r
79 def build_eeprom_image (filename, outfile,vid,pid,devid,cb):
80 """Build a ``C2 Load'' EEPROM image.
82 For details on this format, see section 3.4.3 of
83 the EZ-USB FX2 Technical Reference Manual
84 """
86 image = [
87 0xC2, # boot from EEPROM
88 lsb (vid),
89 msb (vid),
90 lsb (pid),
91 msb (pid),
92 lsb (devid),
93 msb (devid),
94 cb # configuration byte
97 # you could just append all the records..
98 # but that would most likely cause a lot of
99 # extra headers/addrs to be written
100 ihx = ihx_file();
101 records = ihx.read(open(filename))
103 # create image map of all values we're writing data too
104 image_map={}
105 for r in records:
106 addr=r.addr
108 l=len(r.data)
109 while c<l:
110 image_map[addr] = r.data[c]
111 addr += 1
112 c += 1
113 # now create new records based on contiguous image data
114 max_addr = max(image_map.keys())
115 records = []
116 start_addr = 0
118 while start_addr <= max_addr:
119 if not image_map.has_key(start_addr):
120 start_addr += 1
121 continue
122 end_addr = start_addr
123 # add continguous data up to 10 bits long (0x3ff)
124 # is max size, trm 3.4.3
125 size=0
126 while image_map.has_key(end_addr) and size < 0x3ff:
127 end_addr += 1
128 size += 1
130 l = end_addr - start_addr
131 data = []
132 for d in range(l):
133 data.append(image_map [ start_addr + d ])
134 records.append ( ihx_rec ( start_addr, 0, data ) )
135 start_addr = end_addr
138 # 4 byte header that indicates where to load
139 # the immediately follow code bytes.
141 for r in records:
142 image.extend( [
143 msb (len (r.data)),
144 lsb (len (r.data)),
145 msb (r.addr),
146 lsb (r.addr)
148 image.extend(r.data)
151 # writes 0 to CPUCS reg (brings FX2 out of reset)
152 image.extend ( [
153 0x80,
154 0x01,
155 0xe6,
156 0x00,
157 0x00
160 buf=struct.pack ( "B"*len(image), *image )
161 print "iic Image Size" , len(buf)
162 out=open( outfile, 'w')
163 out.write(buf)
164 out.close();
166 if __name__ == '__main__':
167 usage = "usage: %prog [options] firmware.ihx outfile"
168 parser = OptionParser (usage=usage)
169 parser.add_option ( "-v", "--vid", type="int", default=0x04b4,
170 help="Vendor ID for iic c2 image." )
171 parser.add_option ( "-p", "--pid", type="int", default=0x0082,
172 help="Product ID for iic c2 image." )
173 parser.add_option ( "-d", "--devid", type="int", default=0,
174 help="Device ID for iic c2 image." )
175 parser.add_option ( "-c", "--configbyte", type="int", default=0x04,
176 help="Configuration Byte (i2c & disconnect polarity, default 0x04)" )
177 (options, args) = parser.parse_args ()
178 if len (args) != 2:
179 parser.print_help ()
180 sys.exit (1)
182 ihx_filename = args[0]
183 iic_filename = args[1]
184 build_eeprom_image ( ihx_filename, iic_filename, options.vid, options.pid, options.devid, options.configbyte )