7b05344a71
PR: 188808 Submitted by: uffer =============================================================== The sigrok project aims at creating a portable, cross-platform, Free/Libre/Open-Source signal analysis software suite that supports various device types, such as logic analyzers, MSOs, oscilloscopes, multimeters, LCR meters, sound level meters, thermometers, hygrometers, anemometers, light meters, DAQs, dataloggers, function generators, spectrum analyzers, power supplies, GPIB interfaces, and more.
90 lines
2.2 KiB
Python
90 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
##
|
|
## This file is part of the sigrok-util project.
|
|
##
|
|
## Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
|
|
##
|
|
## This program is free software; you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation; either version 3 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## This program is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
##
|
|
|
|
import sys
|
|
import os
|
|
import re
|
|
import struct
|
|
from array import array
|
|
|
|
import parsepe
|
|
|
|
|
|
def find_model(filename):
|
|
filename = os.path.split(filename)[-1]
|
|
m = re.search('^dso([a-z0-9]+)1.sys$', filename, re.I)
|
|
if m:
|
|
model = m.group(1).upper()
|
|
model = model.replace('X86', '').replace('AMD64', '').replace('IA64', '')
|
|
if model == '520A':
|
|
model = '5200A'
|
|
else:
|
|
model = 'unknown'
|
|
|
|
return model
|
|
|
|
|
|
def unsparse(data):
|
|
p = 0
|
|
maxaddr = 0
|
|
blob = array('B', [0] * 0x4000)
|
|
while p <= len(data) and data[p+4] == 0:
|
|
num_bytes = struct.unpack("<H", data[p:p+2])[0]
|
|
address = struct.unpack("<H", data[p+2:p+4])[0]
|
|
chunk = array('B')
|
|
chunk.frombytes(data[p+5:p+5+num_bytes])
|
|
p += 22
|
|
|
|
if address > 0x4000:
|
|
# the FX2 only has 16K RAM. other writes are to registers
|
|
# in the 0xe000 region, skip those
|
|
continue
|
|
|
|
blob[address:address+num_bytes] = chunk
|
|
|
|
if address + num_bytes > maxaddr:
|
|
maxaddr = address + num_bytes
|
|
|
|
return blob[:maxaddr].tostring()
|
|
|
|
|
|
def usage():
|
|
print("sigrok-fwextract-hantek-dso <driverfile>")
|
|
sys.exit()
|
|
|
|
|
|
#
|
|
# main
|
|
#
|
|
|
|
if len(sys.argv) != 2:
|
|
usage()
|
|
|
|
try:
|
|
filename = sys.argv[1]
|
|
binihx = parsepe.extract_symbol(filename, '_firmware')
|
|
if binihx is None:
|
|
raise Exception("no firmware found")
|
|
blob = unsparse(binihx)
|
|
outfile = 'hantek-dso-' + find_model(filename) + '.fw'
|
|
open(outfile, 'wb').write(blob)
|
|
print("saved %d bytes to %s" % (len(blob), outfile))
|
|
except Exception as e:
|
|
print("Error: %s" % str(e))
|