]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - fx2lib/utils/ihx2iic.py
Import fx2lib into fx2lafw directly.
[sigrok-firmware-fx2lafw.git] / fx2lib / utils / ihx2iic.py
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