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
31 from functools
import reduce
36 raise ValueError("Length must be even")
38 for i
in range (0, len(s
), 2):
39 r
.append (int (s
[i
:i
+2], 16))
43 return (x
>> 8) & 0xff
48 class ihx_rec (object):
49 def __init__ (self
, addr
, type, data
):
54 class ihx_file (object):
56 self
.pat
= re
.compile (r
':[0-9A-F]{10,}')
57 def read (self
, file):
60 line
= line
.strip().upper ()
61 if not self
.pat
.match (line
):
62 raise ValueError("Invalid hex record format")
63 bytes
= hex_to_bytes (line
[1:])
64 sum = reduce (lambda x
, y
: x
+ y
, bytes
, 0) % 256
66 raise ValueError("Bad hex checksum")
68 addr
= (bytes
[1] << 8) + bytes
[2]
71 if lenx
!= len (data
):
72 raise ValueError("Invalid hex record (bad length)")
75 r
.append (ihx_rec (addr
, type, data
))
80 def build_eeprom_image (filename
, outfile
,vid
,pid
,devid
,cb
):
81 """Build a ``C2 Load'' EEPROM image.
83 For details on this format, see section 3.4.3 of
84 the EZ-USB FX2 Technical Reference Manual
88 0xC2, # boot from EEPROM
95 cb
# configuration byte
98 # you could just append all the records..
99 # but that would most likely cause a lot of
100 # extra headers/addrs to be written
102 records
= ihx
.read(open(filename
))
104 # create image map of all values we're writing data too
111 image_map
[addr
] = r
.data
[c
]
114 # now create new records based on contiguous image data
115 max_addr
= max(image_map
.keys())
119 while start_addr
<= max_addr
:
120 if start_addr
not in image_map
:
123 end_addr
= start_addr
124 # add continguous data up to 10 bits long (0x3ff)
125 # is max size, trm 3.4.3
127 while end_addr
in image_map
and size
< 0x3ff:
131 l
= end_addr
- start_addr
134 data
.append(image_map
[ start_addr
+ d
])
135 records
.append ( ihx_rec ( start_addr
, 0, data
) )
136 start_addr
= end_addr
139 # 4 byte header that indicates where to load
140 # the immediately follow code bytes.
152 # writes 0 to CPUCS reg (brings FX2 out of reset)
161 buf
=struct
.pack ( "B"*len(image
), *image
)
162 print("iic Image Size" , len(buf
))
163 out
=open( outfile
, 'wb')
167 if __name__
== '__main__':
168 usage
= "usage: %prog [options] firmware.ihx outfile"
169 parser
= OptionParser (usage
=usage
)
170 parser
.add_option ( "-v", "--vid", type="int", default
=0x04b4,
171 help="Vendor ID for iic c2 image." )
172 parser
.add_option ( "-p", "--pid", type="int", default
=0x0082,
173 help="Product ID for iic c2 image." )
174 parser
.add_option ( "-d", "--devid", type="int", default
=0,
175 help="Device ID for iic c2 image." )
176 parser
.add_option ( "-c", "--configbyte", type="int", default
=0x04,
177 help="Configuration Byte (i2c & disconnect polarity, default 0x04)" )
178 (options
, args
) = parser
.parse_args ()
183 ihx_filename
= args
[0]
184 iic_filename
= args
[1]
185 build_eeprom_image ( ihx_filename
, iic_filename
, options
.vid
, options
.pid
, options
.devid
, options
.configbyte
)