from spec.pinfunctions import pinspec
from copy import deepcopy
+
def namesuffix(name, suffix, namelist):
names = []
for n in namelist:
class PinGen(object):
+ """ a meta-helper which creates pins from the pinspec
+ and adds them to the pinouts.
+
+ __call__ is used to effectively create a lambda function, which
+ in combination with setattr (below) gives the function a name
+ in the Pinouts class, according to the pinspec.
+
+ arguments to __call__ (which ends up as Pinouts.i2s, Pinouts.sdmmc
+ and so on, according to spec.pinfunctions.pinspec) are:
+
+ suffix: e.g. GPIO or SD or SPI
+ offs : a tuple of (Bank, Bank offset) as a string, integer
+ mux : which column in the multiplexer
+ start : the start of a subset of pins to be inserted
+ limit : the end of the subset (or the number if start also given)
+ spec : *EXTRA* pins to be inserted (at different implicit positions)
+
+ the pins are inserted with the suffix, starting from the
+ offset position using offs as the row and mux as the column,
+ and working in a constant increment down the rows.
+
+ spec is slightly complicated, basically there's extra
+ functions that we want to be on the same pin (but a different mux)
+ because their use is mutually-exclusive. without this spec
+ argument the extra pins would need to be MANUALLY moved about
+ during the development of the pinmux, if the "main" pins
+ were also moved about. this would be a pain.
+
+ so instead, extra pins are given of the form:
+ { 'EXTRA1' : ('PREEXISTING_NAME', MUX_COLUMN),
+ ...
+ }
+
+ where the function EXTRA1 will always be placed on the SAME ROW
+ as PREEXISTING_NAME, just in MUX_COLUMN. this may be done
+ several times i.e. multiple new EXTRA functions can be added
+ on the same row as PRE_EXISTING_NAME, just with different
+ MUX_COLUMN values.
+
+ Note: spec must implicitly be in the same Bank.
+ """
+
def __init__(self, pinouts, fname, pinfn, bankspec):
self.pinouts = pinouts
self.bankspec = bankspec
self.pinfn = pinfn
self.fname = fname
- def __call__(self, suffix, offs, bank, mux,
- start=None, limit=None, spec=None, origsuffix=None):
- pingroup = self.pinfn(suffix, bank)
+ def __call__(self, suffix, offs, mux,
+ start=None, limit=None, spec=None, origsuffix=None,
+ rev=False):
+ bank = offs[0]
+ pf = self.pinfn(suffix, bank)
+ print "pf", suffix, bank, pf
+ pingroup, gangedgroup, clock = pf
+ if clock:
+ self.pinouts.clocks[self.fname] = clock
if isinstance(pingroup, tuple):
prefix, pingroup = pingroup
else:
prefix = self.fname
- if start and limit:
+ if start and limit: # limit turns into an offset from start
limit = start + limit
- pingroup = pingroup[start:limit]
+ sk = "%s:%s" % (self.fname, str(suffix))
+ print "pingroup pre", sk, pingroup
+ pingroup = pingroup[start:limit] # see comment in spec.pinfunctions
+ if rev:
+ # reverse order of pingroup
+ pingroup.reverse()
+ print "pingroup post", sk, pingroup
+ if self.pinouts.byspec.has_key(sk):
+ self.pinouts.byspec[sk] += pingroup
+ else:
+ self.pinouts.byspec[sk] = deepcopy(pingroup)
pins = Pins(prefix, pingroup, self.bankspec,
suffix, offs, bank, mux,
- spec, origsuffix=suffix)
- self.pinouts.pinmerge(pins)
+ spec, origsuffix=suffix, gangedgrp=gangedgroup)
+ fname = self.pinouts.pinmerge(pins)
+ self.pinouts.setganged(fname, gangedgroup)
# pinouts class
+
class Pinouts(object):
def __init__(self, bankspec):
self.bankspec = bankspec
self.pins = {}
self.fnspec = {}
+ self.ganged = {}
+ self.clocks = {}
+ self.byspec = {}
for fname, pinfn in pinspec:
if isinstance(pinfn, tuple):
name, pinfn = pinfn
else:
name = pinfn.__name__
- setattr(self, name, PinGen(self, fname, pinfn, self.bankspec))
+ pin = PinGen(self, fname, pinfn, self.bankspec)
+ setattr(self, name, pin)
+
+ def setganged(self, fname, grp):
+ grp = map(lambda x: x[:-1], grp)
+ if fname not in self.ganged:
+ self.ganged[fname] = []
+ self.ganged[fname] += grp
def __contains__(self, k):
return k in self.pins
for k in v:
assert k not in self.pins[pinidx], \
"pin %d position %d already taken\n%s\n%s" % \
- (pinidx, k, str(v), self.pins[pinidx])
+ (pinidx, k, str(v), self.pins[pinidx])
self.pins[pinidx].update(v)
def keys(self):
specname = fname + suffix
else:
specname = fname
- #print "fname bank specname suffix ", fname, bank, specname, repr(
+ # print "fname bank specname suffix ", fname, bank, specname, repr(
# suffix)
if specname in self.fnspec[fname]:
# ok so some declarations may bring in different
for (pinidx, v) in fn.pins.items():
self.update(pinidx, v)
+ return fname
+
class Pins(object):
def __init__(self, fname, pingroup, bankspec, suffix, offs, bank, mux,
- spec=None, limit=None, origsuffix=None):
+ spec=None, limit=None, origsuffix=None, gangedgrp=None):
# function type can be in, out or inout, represented by - + *
# strip function type out of each pin name
self.fname = fname
self.pingroup = pingroup
+ self.gangedgroup = gangedgrp
self.bankspec = bankspec
self.suffix = suffix
self.origsuffix = origsuffix or suffix
continue
if name not in spec:
continue
- idx_, mux_, bank_ = spec[name]
+ idx_, mux_ = spec[name]
idx_ = names[idx_]
- pin = {mux_: (name_, bank_)}
+ pin = {mux_: (name_, bank)}
if idx_ in res:
res[idx_].update(pin)
else: