add naming and pin-order reverse option
[pinmux.git] / src / spec / interfaces.py
index 27b008fe33696a76f72a19af912cde9ab0dfa8eb..744f80333985aadb1163fc24bb06e954f83a6ad0 100644 (file)
@@ -3,6 +3,7 @@
 from spec.pinfunctions import pinspec
 from copy import deepcopy
 
+
 def namesuffix(name, suffix, namelist):
     names = []
     for n in namelist:
@@ -20,41 +21,104 @@ class PinGen(object):
         __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: # limit turns into an offset from start
+        if start and limit:  # limit turns into an offset from start
             limit = start + limit
-        pingroup = pingroup[start:limit] # see comment in spec.pinfunctions
+        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
@@ -72,7 +136,7 @@ class Pinouts(object):
             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):
@@ -110,7 +174,7 @@ class Pinouts(object):
             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
@@ -130,11 +194,13 @@ class Pinouts(object):
         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
@@ -153,6 +219,7 @@ class Pins(object):
 
         self.fname = fname
         self.pingroup = pingroup
+        self.gangedgroup = gangedgrp
         self.bankspec = bankspec
         self.suffix = suffix
         self.origsuffix = origsuffix or suffix
@@ -189,9 +256,9 @@ class Pins(object):
                 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: