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
)