123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- # -*- 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.
- # For documentation of the baudrate table see:
- #
- # [AN205] Silicon Labs Application Note 205 Rev. 0.3
- # http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Interface/en/an205.pdf
- import re
- from ConfigParser import ConfigParser
- import cp210x
- from cp210x import VALUES, SIZE_BAUDRATES
- __all__ = ['read_file', 'write_file', 'update_values', 'PrescalerIsZero',
- 'ValuesFileError']
- class ValuesError(StandardError):
- pass
- class PrescalerIsZero(ValuesError):
- pass
- class ValuesFileError(ValuesError):
- pass
- version_pattern = re.compile(r'^\s*(\d\d?)\.(\d\d?)\s*$')
- def read_version(s):
- match = version_pattern.match(s)
- if match is None:
- raise ValueError("Version does not match 'xx.yy'")
- return (int(match.group(1)), int(match.group(2)))
- def write_version(v):
- return "%d.%02d" % v
- def read_hex(s):
- return int(s.strip(), 16)
- def write_hex(num):
- return "%04X" % num
- def write_bool(b):
- if b:
- return 'yes'
- else:
- return 'no'
- def read_bool(s):
- s = s.strip().lower()
- if s not in ['true', 'yes', 'false', 'no']:
- raise ValueError("Boolean must be either 'true', 'yes', 'false' or 'no'.")
- return s in ['true', 'yes']
- def read_baudrate_info(s):
- values = s.split(',')
- if len(values) != 3:
- raise ValueError("Baudrate info must be three comma-separated items")
- try:
- baudgen = read_hex(values[0])
- except ValueError:
- raise ValueError("The first baudrate info must be a hex-value")
- try:
- timer0 = read_hex(values[1])
- except ValueError:
- raise ValueError("The second baudrate info must be a hex-value")
- try:
- prescale = int(values[2])
- except ValueError:
- raise ValueError("The thirdbaudrate info must be a number")
- return (baudgen, timer0, prescale)
- TYPES = {
- 'boolean': (read_bool, write_bool),
- 'int': (int, str),
- 'id': (read_hex, write_hex),
- 'string': (str, str),
- 'version': (read_version, write_version),
- }
- def read_file(fp):
- cp = ConfigParser()
- if isinstance(fp, str):
- cp.read([fp])
- else:
- cp.readfp(fp)
-
- values = {}
-
- for name, type in VALUES:
- if name is 'baudrate_table':
- continue
- reader, _ = TYPES[type]
- if cp.has_option('usb device', name):
- try:
- values[name] = reader(cp.get('usb device', name))
- except ValueError, err:
- raise ValuesFileError("Key '%s': %s" % (name, str(err)))
-
- if cp.has_section('baudrate table'):
- baudrate_table = []
- for name, value in cp.items('baudrate table'):
- try:
- baudrate = int(name)
- except ValueError:
- raise ValuesFileError("Key names in 'baudrate table' must be"
- " baudrate numbers.")
- try:
- baudrate_table.append(read_baudrate_info(value) + (baudrate, ))
- except ValueError, err:
- raise ValuesFileError("Wrong baudrate info %i: %s"
- % (baudrate, str(err)))
- baudrate_table.sort(key=(lambda i: i[3]), reverse=True)
-
- values['baudrate_table'] = baudrate_table
- return values
- def write_file(fp, values):
- fp.write("[usb device]\n")
-
- for name, type in VALUES:
- if name == 'baudrate_table':
- continue
- _, writer = TYPES[type]
- if name in values:
- fp.write("%s = %s\n" % (name, writer(values[name])))
- if 'baudrate_table' in values:
- fp.write("\n")
- fp.write("[baudrate table]\n")
- for (baudgen, timegen, prescaler,
- baudrate) in sorted(values['baudrate_table'], key=(lambda i: i[3]),
- reverse=True):
- fp.write("%7d = %04X, %04X, %d # %s\n"
- % (baudrate, baudgen, timegen, prescaler,
- show_baudrate(baudgen, timegen, prescaler)))
- def calc_baudrate(baudgen, timegen, prescaler):
- # This formulas are from AN205 page 5.
- if prescaler == 0:
- raise PrescalerIsZero("Prescaler is 0")
- baudrate = (24000000. / prescaler) / (0x10000 - baudgen)
- return (baudrate, (0x10000 - timegen) * 2)
- def show_baudrate(baudgen, timegen, prescaler):
- try:
- baudrate, timeout = calc_baudrate(baudgen, timegen, prescaler)
- except PrescalerIsZero:
- return "Wrong data, Prescaler is 0."
- if timeout >= 1000:
- timeout = "%1.3f ms" % (float(timeout) / 1000)
- else:
- timeout = "%d us" % timeout
- if baudrate is None:
- return ", %s" % (baudrate, timeout)
- else:
- return "%7.0f Baud, %s" % (baudrate, timeout)
- def update_values(v, new, dev):
- old_baudrate_table = v.get('baudrate_table')
- new_baudrate_table = new.get('baudrate_table')
-
- v.update(new)
- # update baudrate table
- # it is needed, that the baudrate table has 32 entries when it is written
- # to the eeprom or device.
- if ((old_baudrate_table is not None or new_baudrate_table is not None) and
- (new_baudrate_table is None or
- len(new_baudrate_table) < SIZE_BAUDRATES)):
-
- if old_baudrate_table is not None:
- if len(old_baudrate_table) < SIZE_BAUDRATES:
- baudrate_table = old_baudrate_table
- else:
- baudrate_table = list(merge_baudrate_table(dev.baudrate_table,
- old_baudrate_table))
- else:
- baudrate_table = dev.baudrate_table
-
- if new_baudrate_table:
- baudrate_table = list(merge_baudrate_table(baudrate_table,
- new_baudrate_table))
- v['baudrate_table'] = baudrate_table
-
-
-
- def merge_baudrate_table(old, new):
- for (old_info, (start, stop)) in zip(old, REQUEST_BAUDRATE_RANGES):
- for baudgen, timer, prescaler, baudrate in new:
- if ((start is None or baudrate <= start) and
- baudrate >= stop):
- yield (baudgen, timer, prescaler, baudrate)
- break
- else:
- yield old_info
-
- REQUEST_BAUDRATE_RANGES = [
- # The table data is from AN205 Table 1 on page 1.
- # Start End Default Baudrate
- (None, 2457601), # Undefined
- (2457600, 1474561), # Undefined
- (1474560, 1053258), # Undefined
- (1053257, 670255), # 921600
- ( 670254, 567139), # 576000
- ( 567138, 491521), # 500000
- ( 491520, 273067), # 460800
- ( 273066, 254235), # 256000
- ( 254234, 237833), # 250000
- ( 237832, 156869), # 230400
- ( 156868, 129348), # 153600
- ( 129347, 117029), # 128000
- ( 117028, 77609), # 115200
- ( 77608, 64112), # 76800
- ( 64111, 58054), # 64000
- ( 58053, 56281), # 57600
- ( 56280, 51559), # 56000
- ( 51558, 38602), # 51200
- ( 38601, 28913), # 38400
- ( 28912, 19251), # 28800
- ( 19250, 16063), # 19200
- ( 16062, 14429), # 16000
- ( 14428, 9613), # 14400
- ( 9612, 7208), # 9600
- ( 7207, 4804), # 7200
- ( 4803, 4001), # 4800
- ( 4000, 2401), # 4000
- ( 2400, 1801), # 2400
- ( 1800, 1201), # 1800
- ( 1200, 601), # 1200
- ( 600, 301), # 600
- ( 300, 57), # 300
- ]
|