Revision b96088b6 firmware/fx2/src/common/build_eeprom.py
| b/firmware/fx2/src/common/build_eeprom.py | ||
|---|---|---|
| 29 | 29 |
|
| 30 | 30 |
VID = 0xfffe # Free Software Folks |
| 31 | 31 |
PID = 0x0002 # Universal Software Radio Peripheral |
| 32 |
|
|
| 33 |
|
|
| 34 |
def hex_to_bytes (s): |
|
| 35 |
if len (s) & 0x1: |
|
| 36 |
raise ValueError, "Length must be even" |
|
| 37 |
r = [] |
|
| 38 |
for i in range (0, len(s), 2): |
|
| 39 |
r.append (int (s[i:i+2], 16)) |
|
| 40 |
return r |
|
| 41 | 32 |
|
| 42 | 33 |
def msb (x): |
| 43 | 34 |
return (x >> 8) & 0xff |
| ... | ... | |
| 45 | 36 |
def lsb (x): |
| 46 | 37 |
return x & 0xff |
| 47 | 38 |
|
| 48 |
class ihx_rec (object): |
|
| 49 |
def __init__ (self, addr, type, data): |
|
| 50 |
self.addr = addr |
|
| 51 |
self.type = type |
|
| 52 |
self.data = data |
|
| 53 |
|
|
| 54 |
class ihx_file (object): |
|
| 55 |
def __init__ (self): |
|
| 56 |
self.pat = re.compile (r':[0-9A-F]{10,}')
|
|
| 57 |
def read (self, file): |
|
| 58 |
r = [] |
|
| 59 |
for line in 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 |
|
| 65 |
if sum != 0: |
|
| 66 |
raise ValueError, "Bad hex checksum" |
|
| 67 |
lenx = bytes[0] |
|
| 68 |
addr = (bytes[1] << 8) + bytes[2] |
|
| 69 |
type = bytes[3] |
|
| 70 |
data = bytes[4:-1] |
|
| 71 |
if lenx != len (data): |
|
| 72 |
raise ValueError, "Invalid hex record (bad length)" |
|
| 73 |
if type != 0: |
|
| 74 |
break; |
|
| 75 |
r.append (ihx_rec (addr, type, data)) |
|
| 76 |
|
|
| 77 |
return r |
|
| 78 |
|
|
| 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. |
|
| 82 |
""" |
|
| 83 |
f = open (filename, 'r') |
|
| 84 |
ifx = ihx_file () |
|
| 85 |
r = ifx.read (f) |
|
| 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 |
|
| 90 |
code = [0] * code_len |
|
| 91 |
for x in r: |
|
| 92 |
a = x.addr |
|
| 93 |
l = len (x.data) |
|
| 94 |
code[a-code_start:a-code_start+l] = x.data |
|
| 95 |
return (code_start, code) |
|
| 96 |
|
|
| 97 |
|
|
| 98 | 39 |
def build_eeprom_image (filename, rev): |
| 99 | 40 |
"""Build a ``C2 Load'' EEPROM image. |
| 100 | 41 |
|
| ... | ... | |
| 102 | 43 |
the EZ-USB FX2 Technical Reference Manual |
| 103 | 44 |
""" |
| 104 | 45 |
# get the code we want to run |
| 105 |
(start_addr, bytes) = get_code (filename) |
|
| 46 |
f = open(filename, 'rb') |
|
| 47 |
bytes = f.read() |
|
| 106 | 48 |
|
| 107 | 49 |
devid = rev |
| 50 |
start_addr = 0 #prove me wrong |
|
| 108 | 51 |
|
| 109 | 52 |
rom_header = [ |
| 110 | 53 |
0xC2, # boot from EEPROM |
| ... | ... | |
| 135 | 78 |
0x00 |
| 136 | 79 |
] |
| 137 | 80 |
|
| 138 |
image = rom_header + code_header + bytes + trailer
|
|
| 81 |
image = rom_header + code_header + [ord(c) for c in bytes] + trailer
|
|
| 139 | 82 |
|
| 140 | 83 |
assert (len (image) <= 256) |
| 141 |
return image |
|
| 142 |
|
|
| 143 |
def build_shell_script (out, ihx_filename, rev): |
|
| 144 |
|
|
| 145 |
image = build_eeprom_image (ihx_filename, rev) |
|
| 146 |
|
|
| 147 |
out.write ('#!/bin/sh\n')
|
|
| 148 |
out.write ('usrper -x load_firmware /usr/local/share/usrp/rev%d/std.ihx\n' % rev)
|
|
| 149 |
out.write ('sleep 1\n')
|
|
| 150 |
|
|
| 151 |
# print "len(image) =", len(image) |
|
| 152 |
|
|
| 153 |
i2c_addr = 0x50 |
|
| 154 |
rom_addr = 0x00 |
|
| 155 |
|
|
| 156 |
hex_image = map (lambda x : "%02x" % (x,), image) |
|
| 157 |
|
|
| 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 1\n')
|
|
| 84 |
return image |
|
| 165 | 85 |
|
| 166 | 86 |
if __name__ == '__main__': |
| 167 |
usage = "usage: %prog -r REV [options] bootfile.ihx"
|
|
| 87 |
usage = "usage: %prog -r REV [options] bootfile.bin outfile.bin"
|
|
| 168 | 88 |
parser = OptionParser (usage=usage) |
| 169 | 89 |
parser.add_option ("-r", "--rev", type="int", default=-1,
|
| 170 | 90 |
help="Specify USRP revision number REV (2 or 4)") |
| 171 | 91 |
(options, args) = parser.parse_args () |
| 172 |
if len (args) != 1:
|
|
| 92 |
if len (args) != 2:
|
|
| 173 | 93 |
parser.print_help () |
| 174 | 94 |
sys.exit (1) |
| 175 | 95 |
if options.rev < 0: |
| ... | ... | |
| 177 | 97 |
"You must specify the USRP revision number (2 or 4) with -r REV\n") |
| 178 | 98 |
sys.exit (1) |
| 179 | 99 |
|
| 180 |
ihx_filename = args[0] |
|
| 100 |
infile = args[0] |
|
| 101 |
outfile = args[1] |
|
| 102 |
|
|
| 103 |
image = "".join(chr(c) for c in build_eeprom_image(infile, options.rev)) |
|
| 181 | 104 |
|
| 182 |
build_shell_script (sys.stdout, ihx_filename, options.rev) |
|
| 105 |
f = open(outfile, 'wb') |
|
| 106 |
f.write(str(image)) |
|
| 107 |
f.close() |
|
Also available in: Unified diff