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.
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)
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.
30 from optparse import OptionParser
35 raise ValueError, "Length must be even"
37 for i in range (0, len(s), 2):
38 r.append (int (s[i:i+2], 16))
42 return (x >> 8) & 0xff
47 class ihx_rec (object):
48 def __init__ (self, addr, type, data):
53 class ihx_file (object):
55 self.pat = re.compile (r':[0-9A-F]{10,}')
56 def read (self, 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
65 raise ValueError, "Bad hex checksum"
67 addr = (bytes[1] << 8) + bytes[2]
70 if lenx != len (data):
71 raise ValueError, "Invalid hex record (bad length)"
74 r.append (ihx_rec (addr, type, data))
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
87 0xC2, # boot from EEPROM
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
101 records = ihx.read(open(filename))
103 # create image map of all values we're writing data too
110 image_map[addr] = r.data[c]
113 # now create new records based on contiguous image data
114 max_addr = max(image_map.keys())
118 while start_addr <= max_addr:
119 if not image_map.has_key(start_addr):
122 end_addr = start_addr
123 # add continguous data up to 10 bits long (0x3ff)
124 # is max size, trm 3.4.3
126 while image_map.has_key(end_addr) and size < 0x3ff:
130 l = end_addr - start_addr
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.
151 # writes 0 to CPUCS reg (brings FX2 out of reset)
160 buf=struct.pack ( "B"*len(image), *image )
161 print "iic Image Size" , len(buf)
162 out=open( outfile, 'w')
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 ()
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 )