]>
Commit | Line | Data |
---|---|---|
3608c106 UH |
1 | #!/usr/bin/env python |
2 | # | |
3 | # Copyright 2009, Ubixum, Inc | |
4 | # | |
5 | # This file copied and modified for fx2lib from the GnuRadio project | |
6 | # | |
7 | # Copyright 2004,2006 Free Software Foundation, Inc. | |
8 | # | |
9 | # This file is part of GNU Radio | |
10 | # | |
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. | |
15 | # | |
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. | |
20 | # | |
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. | |
25 | # | |
26 | ||
27 | import re | |
28 | import sys, struct | |
29 | import os, os.path | |
30 | from optparse import OptionParser | |
31 | ||
32 | ||
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 | |
40 | ||
41 | def msb (x): | |
42 | return (x >> 8) & 0xff | |
43 | ||
44 | def lsb (x): | |
45 | return x & 0xff | |
46 | ||
47 | class ihx_rec (object): | |
48 | def __init__ (self, addr, type, data): | |
49 | self.addr = addr | |
50 | self.type = type | |
51 | self.data = data | |
52 | ||
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)) | |
75 | ||
76 | return r | |
77 | ||
78 | ||
79 | def build_eeprom_image (filename, outfile,vid,pid,devid,cb): | |
80 | """Build a ``C2 Load'' EEPROM image. | |
81 | ||
82 | For details on this format, see section 3.4.3 of | |
83 | the EZ-USB FX2 Technical Reference Manual | |
84 | """ | |
85 | ||
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 | |
95 | ] | |
96 | ||
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)) | |
102 | ||
103 | # create image map of all values we're writing data too | |
104 | image_map={} | |
105 | for r in records: | |
106 | addr=r.addr | |
107 | c=0 | |
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 | |
117 | ||
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 | |
129 | ||
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 | |
136 | ||
137 | ||
138 | # 4 byte header that indicates where to load | |
139 | # the immediately follow code bytes. | |
140 | ||
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) | |
147 | ]) | |
148 | image.extend(r.data) | |
149 | ||
150 | ||
151 | # writes 0 to CPUCS reg (brings FX2 out of reset) | |
152 | image.extend ( [ | |
153 | 0x80, | |
154 | 0x01, | |
155 | 0xe6, | |
156 | 0x00, | |
157 | 0x00 | |
158 | ] ) | |
159 | ||
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(); | |
165 | ||
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) | |
181 | ||
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 ) | |
185 | ||
186 |