3 # Copyright 2004,2006 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
26 from optparse import OptionParser
28 # USB Vendor and Product ID's
30 VID = 0xfffe # Free Software Folks
31 PID = 0x0002 # Universal Software Radio Peripheral
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))
79 def get_code (filename):
80 """Read the intel hex format file FILENAME and return a tuple
81 of the code starting address and a list of bytes to load there.
83 f = open (filename, 'r')
86 r.sort (lambda a,b: a.addr - b.addr)
87 code_start = r[0].addr
88 code_end = r[-1].addr + len (r[-1].data)
89 code_len = code_end - code_start
94 code[a-code_start:a-code_start+l] = x.data
95 return (code_start, code)
98 def build_eeprom_image (filename, rev):
99 """Build a ``C2 Load'' EEPROM image.
101 For details on this format, see section 3.4.3 of
102 the EZ-USB FX2 Technical Reference Manual
104 # get the code we want to run
105 (start_addr, bytes) = get_code (filename)
110 0xC2, # boot from EEPROM
117 0 # configuration byte
120 # 4 byte header that indicates where to load
121 # the immediately follow code bytes.
129 # writes 0 to CPUCS reg (brings FX2 out of reset)
138 image = rom_header + code_header + bytes + trailer
140 assert (len (image) <= 256)
143 def build_shell_script (out, ihx_filename, rev, prefix):
145 image = build_eeprom_image (ihx_filename, rev)
147 out.write ('#!/bin/sh\n')
148 out.write ('usrper -x load_firmware ' + prefix + '/share/usrp/rev%d/std.ihx\n' % rev)
149 out.write ('sleep 2\n')
151 # print "len(image) =", len(image)
156 hex_image = map (lambda x : "%02x" % (x,), image)
158 while (len (hex_image) > 0):
159 l = min (len (hex_image), 16)
160 out.write ('usrper i2c_write 0x%02x %02x%s\n' %
161 (i2c_addr, rom_addr, ''.join (hex_image[0:l])))
162 hex_image = hex_image[l:]
163 rom_addr = rom_addr + l
164 out.write ('sleep 2\n')
166 if __name__ == '__main__':
167 usage = "usage: %prog -p PREFIX -r REV [options] bootfile.ihx"
168 parser = OptionParser (usage=usage)
169 parser.add_option ("-p", "--prefix", type="string", default="",
170 help="Specify install prefix from configure")
171 parser.add_option ("-r", "--rev", type="int", default=-1,
172 help="Specify USRP revision number REV (2 or 4)")
173 (options, args) = parser.parse_args ()
179 "You must specify the USRP revision number (2 or 4) with -r REV\n")
181 if options.prefix == "":
183 "You must specify the install prefix with -p PREFIX\n")
186 ihx_filename = args[0]
188 build_shell_script (sys.stdout, ihx_filename, options.rev, options.prefix)