sigrok-fwextract-hantek-dso: Add manpage.
[sigrok-util.git] / firmware / hantek-dso / sigrok-fwextract-hantek-dso
1 #!/usr/bin/python3
2 ##
3 ## This file is part of the sigrok-util project.
4 ##
5 ## Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
6 ##
7 ## This program 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 of the License, or
10 ## (at your option) any later version.
11 ##
12 ## This program 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.
16 ##
17 ## You should have received a copy of the GNU General Public License
18 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
19 ##
20
21 import sys
22 import os
23 import re
24 import struct
25 from array import array
26
27 import parsepe
28
29
30 def find_model(filename):
31         filename = os.path.split(filename)[-1]
32         m = re.search('^dso([a-z0-9]+)1.sys$', filename, re.I)
33         if m:
34                 model = m.group(1).upper()
35                 model = model.replace('X86', '').replace('AMD64', '').replace('IA64', '')
36                 if model == '520A':
37                         model = '5200A'
38         else:
39                 model = 'unknown'
40
41         return model
42
43
44 def unsparse(data):
45         p = 0
46         maxaddr = 0
47         blob = array('B', [0] * 0x4000)
48         while p <= len(data) and data[p+4] == 0:
49                 num_bytes = struct.unpack("<H", data[p:p+2])[0]
50                 address = struct.unpack("<H", data[p+2:p+4])[0]
51                 chunk = array('B')
52                 chunk.frombytes(data[p+5:p+5+num_bytes])
53                 p += 22
54
55                 if address > 0x4000:
56                         # the FX2 only has 16K RAM. other writes are to registers
57                         # in the 0xe000 region, skip those
58                         continue
59
60                 blob[address:address+num_bytes] = chunk
61
62                 if address + num_bytes > maxaddr:
63                         maxaddr = address + num_bytes
64
65         return blob[:maxaddr].tostring()
66
67
68 def usage():
69         print("sigrok-fwextract-hantek-dso <driverfile>")
70         sys.exit()
71
72
73 #
74 # main
75 #
76
77 if len(sys.argv) != 2:
78         usage()
79
80 try:
81         filename = sys.argv[1]
82         binihx = parsepe.extract_symbol(filename, '_firmware')
83         if binihx is None:
84                 raise Exception("no firmware found")
85         blob = unsparse(binihx)
86         outfile = 'hantek-dso-' + find_model(filename) + '.fw'
87         open(outfile, 'wb').write(blob)
88         print("saved %d bytes to %s" % (len(blob), outfile))
89 except Exception as e:
90         print("Error: %s" % str(e))
91
92
93