2b66a4ac0589142e33ea477e198af7f6031bb9db
[debian/gnuradio] / usrp2 / firmware / u2_flash_tool
1 #!/usr/bin/env python
2
3 import sys
4 from optparse import OptionParser
5
6 SECTOR_SIZE = 512                 # bytes
7 MAX_FILE_SIZE =  1 * (2**20)      # maximum number of bytes we'll burn to a slot
8
9 FPGA_OFFSET = 0                   # offset in flash to fpga image
10 FIRMWARE_OFFSET = 1 * (2**20)     # offset in flash to firmware image
11
12 def read_file_data(filename):
13     f = open(filename, "rb")
14     file_data = f.read(MAX_FILE_SIZE)
15     t = len(file_data) % SECTOR_SIZE
16     if t != 0:
17         file_data += (SECTOR_SIZE - t)*chr(0)  # pad to an even sector size w/ zeros
18     return file_data
19
20
21 def write_flash(offset, filename, devname):
22     file_data = read_file_data(filename)
23     dev = open(devname, "wb")
24     dev.seek(offset, 0)                 # seek to absolute byte offset
25     dev.write(file_data)
26     dev.flush()
27     dev.close()
28     return True
29
30
31 def verify_flash(offset, filename, devname):
32     file_data = read_file_data(filename)
33     dev = open(devname, "rb")
34     dev.seek(offset, 0)                 # seek to absolute byte offset
35     dev_data = dev.read(len(file_data))
36     if len(dev_data) != len(file_data):
37         sys.stderr.write("short read on device %s\n" % (devname,))
38         return False
39
40     if file_data == dev_data:
41         return True
42
43     # doesn't match
44     nwrong = 0
45     for i in range(len(file_data)):
46         if dev_data[i] != file_data[i]:
47             sys.stderr.write("mismatch at offset %7d.  Expected 0x%02x, got 0x%02x\n" % (
48                 i, ord(file_data[i]), ord(dev_data[i])))
49             nwrong += 1
50             if nwrong > 16:
51                 sys.stderr.write("> 16 errors, stopping comparison\n")
52                 break
53     return False
54
55 def read_flash(offset, filename, devname):
56     dev = open(devname, "rb")
57     dev.seek(offset, 0)                 # seek to absolute byte offset
58     dev_data = dev.read(MAX_FILE_SIZE)
59     dev.close()
60     open(filename, "wb").write(dev_data)
61
62     
63 def main():
64     parser = OptionParser(usage="%prog: [options] filename")
65     parser.add_option("-w", "--write", action="store_const", const="write", dest="mode",
66                       help="write FILE to TARGET slot")
67     parser.add_option("-v", "--verify",  action="store_const", const="verify", dest="mode",
68                       help="verify FILE against TARGET slot")
69     parser.add_option("-r", "--read",  action="store_const", const="read", dest="mode",
70                       help="read TARGET slot, write to FILE")
71     parser.add_option("-t", "--target", type="choice", choices=("fpga", "s/w"), default="s/w",
72                       help="select TARGET slot from: fpga, s/w [default=%default]")
73     parser.add_option("", "--dev", default=None,
74                       help="specify flash device file, e.g., /dev/sdb.  Be careful!")
75     parser.set_defaults(target="s/w", mode=None)
76
77     (options, args) = parser.parse_args()
78     if len(args) != 1:
79         parser.print_help()
80         raise SystemExit
81
82     filename = args[0]
83
84     if options.mode is None:
85         sys.stderr.write("specify mode with -w, -v or -r\n")
86         parser.print_help()
87         raise SystemExit
88
89     if options.dev is None:
90         sys.stderr.write("specify the device file with --dev\n")
91         parser.print_help()
92         raise SystemExit
93
94     offset = { "fpga" : FPGA_OFFSET, "s/w" : FIRMWARE_OFFSET }[options.target]
95     
96     if options.mode == "write":
97         r = (write_flash(offset, filename, options.dev)
98              and verify_flash(offset, filename, options.dev))
99     elif options.mode == "verify":
100         r = verify_flash(offset, filename, options.dev)
101     elif options.mode == "read":
102         r = read_flash(offset, filename, options.dev)
103     else:
104         raise NotImplemented
105
106     if not r:
107         raise SystemExit, 1
108
109
110 if __name__ == "__main__":
111     main()
112
113     
114
115
116