summaryrefslogtreecommitdiffstats
path: root/contrib/cp210x-program/build/lib/cp210x/eeprom.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cp210x-program/build/lib/cp210x/eeprom.py')
-rw-r--r--contrib/cp210x-program/build/lib/cp210x/eeprom.py180
1 files changed, 180 insertions, 0 deletions
diff --git a/contrib/cp210x-program/build/lib/cp210x/eeprom.py b/contrib/cp210x-program/build/lib/cp210x/eeprom.py
new file mode 100644
index 0000000..25f0372
--- /dev/null
+++ b/contrib/cp210x-program/build/lib/cp210x/eeprom.py
@@ -0,0 +1,180 @@
+# -*- 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.
+
+import cp210x
+from cp210x import from_binary, to_binary, iif, VALUES
+
+__all__ = ['EEPROM', 'HexFileError']
+
+POS_BAUDRATE_TABLE = 0x0000
+POS_PART_NUMBER = 0x01FF
+POS_PRODUCT_STRING = 0x0208
+POS_SERIAL_NUMBER = 0x0307
+POS_PRODUCT_ID = 0x0390
+POS_VENDOR_ID = 0x0392
+POS_VERSION = 0x0394
+POS_CFG_ATTRIBUTES = 0x03A1
+POS_MAX_POWER = 0x03A2
+POS_VENDOR_STRING = 0x03C3
+POS_LOCK_VALUE = 0x03FF
+
+class HexFileError(StandardError):
+ pass
+
+def checksum(line):
+ return sum(ord(c) for c in line) & 0xFF
+
+def _int_value(position, size, read=lambda x:x, write=lambda x:x):
+ def get(self):
+ return read(from_binary(self.get(position, size)))
+ def set(self, value):
+ self.set(position, to_binary(write(value), size))
+ return property(get, set)
+
+def _str_value(position, max_size):
+ def get(self):
+ size = from_binary(self.get(position, 1))
+ assert size <= (max_size + 2) and size >= 2
+ assert self.get(position + 1, 1) == '\x03', "Missing 0x03 at %04X" % (position + 1)
+ return self.get(position + 2, size - 2).decode('utf-16-le')
+
+ def set(self, value):
+ encoded = value.encode('utf-16-le')
+ assert len(encoded) <= max_size
+ self.set(position, chr(len(encoded) + 2) + '\x03' + encoded)
+
+ return property(get, set)
+
+class EEPROM(object):
+ START_ADDRESS = 0x3600
+ def __init__(self, content=None):
+ if isinstance(content, str) or content is None:
+ assert content is None or len(content) == cp210x.SIZE_EEPROM
+ self.content = content
+ elif isinstance(content, cp210x.Cp210xProgrammer):
+ self.content = content.get_eeprom_content()
+ else:
+ self.parse_hex_file(content.read())
+
+ def write_to_cp210x(self, cp210xDevice):
+ cp210xDevice.set_eeprom_content(self.content)
+
+ def parse_hex_file(self, hex_content):
+ self.content = ''
+ address = self.START_ADDRESS
+ for tag in hex_content.split('\n'):
+ if not tag.startswith(':'):
+ raise HexFileError("Line doesn't start with ':'")
+
+ try:
+ content = tag[1:].decode('hex')
+ except TypeError:
+ raise HexFileError("Hex data expected")
+
+ if len(content) < 5:
+ raise HexFileError("Line to short")
+
+ if checksum(content) != 0:
+ raise HexFileError("Checksum error")
+
+ size = from_binary(content[0])
+ tag_address = from_binary(content[1:3], le=False)
+ tag_type = from_binary(content[3:4])
+ line = content[4:-1]
+
+ if tag_type == 0x00:
+ if tag_address != address:
+ raise HexFileError("Expected address %04X but found %04X"
+ % (address, tag_address))
+ self.content += line
+ address += len(line)
+ elif tag_type == 0x01:
+ if size != 0 or len(line) != 0:
+ raise HexFileError("Defekt end tag")
+ break
+
+ else:
+ raise HexFileError("Unknown tag type %02X" % tag_type)
+
+ def build_hex_file(self):
+ for tag_start in range(0, len(self.content), 0x10):
+ line = self.content[tag_start:tag_start+0x10]
+ address = self.START_ADDRESS + tag_start
+ tag = (to_binary(len(line), 1) +
+ to_binary(address, le=False) +
+ '\x00' +
+ line)
+ cs = checksum(tag)
+ if cs == 0:
+ tag += '\x00'
+ else:
+ tag += chr(0x100 - cs)
+ yield ":%s\n" % tag.encode('hex')
+ yield ":00000001FF\n"
+
+ def write_hex_file(self, f):
+ if isinstance(f, str):
+ f = file(f, 'wb')
+ do_close = True
+ else:
+ do_close = False
+ for line in self.build_hex_file():
+ f.write(line)
+ if do_close:
+ f.close()
+
+ def read_hex_file(self, f):
+ if isinstance(f, str):
+ f = file(f, 'rb')
+ do_close = True
+ else:
+ do_close = False
+ self.parse_hex_file(f.read())
+ if do_close:
+ f.close()
+
+ def get(self, pos, length):
+ return self.content[pos:pos+length]
+
+ def set(self, pos, data):
+ self.content = (self.content[:pos] +
+ data +
+ self.content[pos + len(data):])
+
+ def _get_baudrate_table(self):
+ dat = self.get(POS_BAUDRATE_TABLE, cp210x.SIZE_BAUDRATE_TABLE)
+ return [cp210x.parse_baudrate_cfg(dat[pos:pos+cp210x.SIZE_BAUDRATE_CFG])
+ for pos in range(0, cp210x.SIZE_BAUDRATE_TABLE,
+ cp210x.SIZE_BAUDRATE_CFG)]
+ def _set_baudrate_table(self, baudrates):
+ assert len(baudrates) == cp210x.SIZE_BAUDRATES
+ self.set(POS_BAUDRATE_TABLE,
+ ''.join(cp210x.build_baudrate_cfg(*cfg) for cfg in baudrates))
+ baudrate_table = property(_get_baudrate_table, _set_baudrate_table)
+ product_string = _str_value(POS_PRODUCT_STRING, cp210x.SIZE_PRODUCT_STRING)
+ serial_number = _str_value(POS_SERIAL_NUMBER, cp210x.SIZE_SERIAL_NUMBER)
+ part_number = _int_value(POS_PART_NUMBER, 1)
+ product_id = _int_value(POS_PRODUCT_ID, 2)
+ vendor_id = _int_value(POS_VENDOR_ID, 2)
+ version = _int_value(POS_VERSION, 2,
+ cp210x.from_bcd2, cp210x.to_bcd2)
+ bus_powered = _int_value(POS_CFG_ATTRIBUTES, 1,
+ lambda a: bool(a & 0x40),
+ lambda a: iif(a, 0xC0, 0x80))
+ max_power = _int_value(POS_MAX_POWER, 1, lambda p: p*2, cp210x.to_div2)
+ vendor_string = _str_value(POS_VENDOR_STRING, cp210x.SIZE_VENDOR_STRING)
+ locked = _int_value(POS_LOCK_VALUE, 1,
+ lambda l: l == cp210x.LCK_LOCKED,
+ lambda b: iif(b, cp210x.LCK_LOCKED,
+ cp210x.LCK_UNLOCKED))
+
+ def get_values(self):
+ return dict((name, getattr(self, name)) for name, type in VALUES)
+
+ def set_values(self, values):
+ for name, value in values.items():
+ setattr(self, name, value)
+
+