summaryrefslogtreecommitdiffstats
path: root/contrib/cp210x-program/cp210x-program
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cp210x-program/cp210x-program')
-rwxr-xr-xcontrib/cp210x-program/cp210x-program266
1 files changed, 266 insertions, 0 deletions
diff --git a/contrib/cp210x-program/cp210x-program b/contrib/cp210x-program/cp210x-program
new file mode 100755
index 0000000..be97be8
--- /dev/null
+++ b/contrib/cp210x-program/cp210x-program
@@ -0,0 +1,266 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2007 Johannes Hölzl <johannes.hoelzl@gmx.de>
+#
+# This library is covered by the GNU LGPL, read LICENSE for details.
+"""\
+Provides access to the EEPROM in an Silabs CP210x. The data can be directly to
+the device read or written.
+"""
+__author__ = "Johannes Hölzl <johannes.hoelzl@gmx.de>"
+__license__ = "GNU LGPL"
+__version__ = "0.2"
+
+import sys
+import re
+import string
+import traceback
+import optparse
+
+from cp210x import usb, valuefile, cp210x
+from cp210x.eeprom import EEPROM, HexFileError
+from cp210x.valuefile import read_baudrate_info, update_values, ValuesFileError
+TRANS_UNDERSCORE = string.maketrans('_', '-')
+
+ERR_OK = 0
+ERR_WRONG_INPUT = -1
+ERR_INTERNAL = -2
+ERR_DEVICE_LOCKED = -3
+ERR_DEVICE_NOT_FOUND = -4
+ERR_DEVICE_ERROR = -5
+
+def error(message, retval=-1):
+ sys.stderr.write(message + "\n")
+ sys.exit(retval)
+
+class Option(optparse.Option):
+ TYPES = list(optparse.Option.TYPES)
+ TYPE_CHECKER = dict(optparse.Option.TYPE_CHECKER)
+ for type, (reader, _) in valuefile.TYPES.items():
+ if type in TYPES:
+ continue
+ TYPES.append(type)
+ def checker(self, name, value, reader=reader):
+ try:
+ return reader(value)
+ except ValueError, err:
+ raise optparse.OptionValueError("option %s: %s" % (name,
+ str(err)))
+ TYPE_CHECKER[type] = checker
+
+class OptionParser(optparse.OptionParser):
+ def error(self, msg):
+ error(msg, ERR_WRONG_INPUT)
+
+ def __init__(self, *args, **kwargs):
+ if 'option_class' not in kwargs:
+ kwargs['option_class'] = Option
+ optparse.OptionParser.__init__(self, *args, **kwargs)
+
+def input_file(arg):
+ if arg is None or arg == '-':
+ return sys.stdin
+ else:
+ return file(arg, 'rb')
+
+def output_file(arg):
+ if arg is None or arg == '-':
+ return sys.stdout
+ else:
+ return file(arg, 'wb')
+
+def options_to_values(options):
+ values = {}
+ for name, type in cp210x.VALUES:
+ if name == "baudrate_table":
+ continue
+ value = getattr(options, name)
+ if value is not None:
+ values[name] = value
+
+ if options.baudrate_table:
+ baudrate_table = []
+ for s in options.baudrate_table:
+ try:
+ baudrate, info = s.split(':')
+ except TypeError:
+ error("option --set-baudrate: need two parts separated by ':'",
+ ERR_WRONG_INPUT)
+ try:
+ baudrate_table.append(read_baudrate_info(info) +
+ (int(baudrate), ))
+ except ValueError, err:
+ error("option --set-baudrate: %s" % str(err),
+ ERR_WRONG_INPUT)
+
+ values['baudrate_table'] = baudrate_table
+ return values
+
+def find_device(patterns):
+ usb_patterns = []
+ for pattern in patterns:
+ if ':' in pattern:
+ try:
+ vidString, pidString = pattern.split(':')
+ vid = int(vidString, 16)
+ pid = int(pidString, 16)
+
+ except (TypeError, ValueError):
+ error("Match be either 'ddd/ddd' or 'hhhh:hhhh'.",
+ ERR_WRONG_INPUT)
+
+ usb_patterns.append(dict(idVendor=vid, idProduct=pid))
+ elif '/' in pattern:
+ try:
+ bus, device = pattern.split('/')
+ usb_patterns.append( (bus, device) )
+ except (TypeError, ValueError):
+ error("Match be either 'ddd/ddd' or 'hhhh:hhhh'.",
+ ERR_WRONG_INPUT)
+ else:
+ error("Match be either 'ddd/ddd' or 'hhhh:hhhh'.",
+ ERR_WRONG_INPUT)
+
+ for dev in cp210x.Cp210xProgrammer.list_devices(usb_patterns):
+ return dev
+
+ error("No devices found", ERR_DEVICE_NOT_FOUND)
+
+def read_cp210x(options):
+ dev = find_device(options.match)
+ dev.open()
+ try:
+ eeprom = EEPROM(dev)
+ finally:
+ dev.close()
+
+ if options.hex_output:
+ eeprom.write_hex_file(output_file(options.hex_output))
+ if options.ini_output or not options.hex_output:
+ valuefile.write_file(output_file(options.ini_output), eeprom.get_values())
+
+def write_cp210x(options):
+ dev = find_device(options.match)
+ dev.open()
+ try:
+ if options.hex_input or options.force_eeprom:
+
+ if options.hex_input:
+ eeprom = EEPROM(input_file(options.hex_input))
+ else:
+ eeprom = EEPROM(dev)
+
+ values = eeprom.get_values()
+ if options.ini_input:
+ values = valuefile.read_file(input_file(options.ini_input))
+ update_values(values, options_to_values(options), eeprom)
+
+ eeprom.set_values(values)
+
+ eeprom.write_to_cp210x(dev)
+ if options.reset_device:
+ dev.reset()
+
+ else:
+ if options.ini_input:
+ values = valuefile.read_file(input_file(options.ini_input))
+ else:
+ values = {}
+ update_values(values, options_to_values(options), dev)
+ dev.set_values(values)
+
+ if options.reset_device:
+ dev.reset()
+ finally:
+ dev.close()
+
+def change_hexfile(options):
+ eeprom = EEPROM(input_file(options.hex_input))
+ values = {}
+ if options.ini_input:
+ update_values(values,
+ valuefile.read_file(input_file(options.ini_input)),
+ eeprom)
+ update_values(values, options_to_values(options), eeprom)
+ eeprom.set_values(values)
+ if options.ini_output:
+ valuefile.write_file(output_file(options.ini_output),
+ eeprom.get_values())
+ eeprom.write_hex_file(output_file(options.hex_output))
+
+def parse_hexfile(options):
+ eeprom = EEPROM(input_file(options.hex_input))
+ valuefile.write_file(output_file(options.ini_output), eeprom.get_values())
+
+parser = OptionParser(version=__version__, description=__doc__)
+parser.add_option("-r", "--read-cp210x", const=read_cp210x,
+ dest="action", action="store_const")
+parser.add_option("-w", "--write-cp210x", const=write_cp210x,
+ dest="action", action="store_const")
+parser.add_option("-c", "--change-hexfile", const=change_hexfile,
+ dest="action", action="store_const")
+parser.add_option("-p", "--parse-hexfile", const=parse_hexfile,
+ dest="action", action="store_const")
+parser.add_option("-F", "--hex-input", metavar="FILE")
+parser.add_option("-f", "--hex-output", metavar="FILE")
+parser.add_option("-I", "--ini-input", metavar="FILE")
+parser.add_option("-i", "--ini-output", metavar="FILE")
+for name, type in cp210x.VALUES:
+ if name == 'baudrate_table':
+ continue
+ parser.add_option("--set-" + name.translate(TRANS_UNDERSCORE),
+ dest=name, metavar=name.upper(), type=type)
+parser.add_option("--set-baudrate", action="append", dest="baudrate_table")
+parser.add_option("-m", "--match", action="append", metavar="PATTERN")
+parser.add_option("--reset-device", action="store_true")
+parser.add_option("--force-eeprom", action="store_true")
+
+parser.set_defaults(
+ action=read_cp210x,
+ hex_input=None,
+ hex_output=None,
+ ini_input=None,
+ ini_output=None,
+ match=[],
+ baudrate_table=[],
+ reset_device=False,
+ force_eeprom=False,
+)
+
+def main():
+ (options, _) = parser.parse_args()
+ if not options.match:
+ options.match = ['10C4:EA60', '10C4:EA61','413C:9500' ]
+ options.action(options)
+
+if __name__ == '__main__':
+ try:
+ usb.init()
+ main()
+
+ except cp210x.DeviceLocked:
+ error("Can not write data to device. Device is locked.",
+ ERR_DEVICE_LOCKED)
+
+ except cp210x.Cp210xError, err:
+ error(str(err), ERR_DEVICE_ERROR)
+
+ except IOError, err:
+ error(str(err), ERR_OTHER)
+
+ except HexFileError, err:
+ error(str(err), ERR_OTHER)
+
+ except ValuesFileError, err:
+ error(str(err), ERR_OTHER)
+
+ except usb.LibUsbNotInstalled:
+ error("Package 'libusb' not installed.")
+
+ except SystemExit, err:
+ raise
+
+ except:
+ traceback.print_exc()
+ sys.exit(ERR_INTERNAL)
+