3 from spec
.pinfunctions
import pinspec
4 from copy
import deepcopy
7 def namesuffix(name
, suffix
, namelist
):
11 names
.append("%s%s_%s" % (name
, suffix
, n
))
13 names
.append("%s_%s" % (name
, suffix
))
18 """ a meta-helper which creates pins from the pinspec
19 and adds them to the pinouts.
21 __call__ is used to effectively create a lambda function, which
22 in combination with setattr (below) gives the function a name
23 in the Pinouts class, according to the pinspec.
25 arguments to __call__ (which ends up as Pinouts.i2s, Pinouts.sdmmc
26 and so on, according to spec.pinfunctions.pinspec) are:
28 suffix: e.g. GPIO or SD or SPI
29 offs : a tuple of (Bank, Bank offset) as a string, integer
30 mux : which column in the multiplexer
31 start : the start of a subset of pins to be inserted
32 limit : the end of the subset (or the number if start also given)
33 spec : *EXTRA* pins to be inserted.
35 spec is slightly complicated, basically there's extra
36 functions that we want to be on the same pin (but a different mux)
37 because their use is mutually-exclusive. without this spec
38 argument the extra pins would need to be MANUALLY moved about
39 during the development of the pinmux, if the "main" pins
40 were also moved about. this would be a pain.
42 so instead, extra pins are given of the form:
43 { 'EXTRA1' : ('PREEXISTING_NAME', MUX_COLUMN),
47 where the function EXTRA1 will always be placed on the SAME ROW
48 as PREEXISTING_NAME, just in MUX_COLUMN. this may be done
49 several times i.e. multiple new EXTRA functions can be added
50 on the same row as PRE_EXISTING_NAME, just with different
53 Note: spec must implicitly be in the same Bank.
56 def __init__(self
, pinouts
, fname
, pinfn
, bankspec
):
57 self
.pinouts
= pinouts
58 self
.bankspec
= bankspec
62 def __call__(self
, suffix
, offs
, mux
,
63 start
=None, limit
=None, spec
=None, origsuffix
=None):
65 pingroup
, gangedgroup
= self
.pinfn(suffix
, bank
)
66 if isinstance(pingroup
, tuple):
67 prefix
, pingroup
= pingroup
70 if start
and limit
: # limit turns into an offset from start
72 pingroup
= pingroup
[start
:limit
] # see comment in spec.pinfunctions
73 pins
= Pins(prefix
, pingroup
, self
.bankspec
,
74 suffix
, offs
, bank
, mux
,
75 spec
, origsuffix
=suffix
, gangedgrp
=gangedgroup
)
76 fname
= self
.pinouts
.pinmerge(pins
)
77 self
.pinouts
.setganged(fname
, gangedgroup
)
82 class Pinouts(object):
83 def __init__(self
, bankspec
):
84 self
.bankspec
= bankspec
88 for fname
, pinfn
in pinspec
:
89 if isinstance(pinfn
, tuple):
93 setattr(self
, name
, PinGen(self
, fname
, pinfn
, self
.bankspec
))
95 def setganged(self
, fname
, grp
):
96 self
.ganged
[fname
] = map(lambda x
: x
[:-1], grp
)
98 def __contains__(self
, k
):
101 def has_key(self
, k
):
102 return k
in self
.pins
104 def add_spec(self
, k
, v
):
107 def update(self
, pinidx
, v
):
108 if pinidx
not in self
.pins
:
109 self
.pins
[pinidx
] = v
112 assert k
not in self
.pins
[pinidx
], \
113 "pin %d position %d already taken\n%s\n%s" % \
114 (pinidx
, k
, str(v
), self
.pins
[pinidx
])
115 self
.pins
[pinidx
].update(v
)
118 return self
.pins
.keys()
121 return self
.pins
.items()
127 return len(self
.pins
)
129 def __delitem__(self
, k
):
132 def __getitem__(self
, k
):
135 def pinmerge(self
, fn
):
136 # hack, store the function specs in the pins dict
138 suffix
= fn
.origsuffix
141 if not hasattr(self
, 'fnspec'):
145 assert 'EINT' not in self
146 if fname
not in self
.fnspec
:
147 self
.add_spec(fname
, {})
148 if suffix
or fname
== 'EINT' or fname
== 'PWM':
149 specname
= fname
+ suffix
152 # print "fname bank specname suffix ", fname, bank, specname, repr(
154 if specname
in self
.fnspec
[fname
]:
155 # ok so some declarations may bring in different
156 # names at different stages (EINT, PWM, flexbus1/2)
157 # so we have to merge the names in. main thing is
159 tomerge
= self
.fnspec
[fname
][specname
]
160 for p
in fn
.pingroup
:
161 if p
not in tomerge
.pingroup
:
162 tomerge
.pingroup
.append(p
)
163 tomerge
.pins
.update(fn
.pins
)
164 tomerge
.fntype
.update(fn
.fntype
)
166 self
.fnspec
[fname
][specname
] = deepcopy(fn
)
169 for (pinidx
, v
) in fn
.pins
.items():
170 self
.update(pinidx
, v
)
177 def __init__(self
, fname
, pingroup
, bankspec
, suffix
, offs
, bank
, mux
,
178 spec
=None, limit
=None, origsuffix
=None, gangedgrp
=None):
180 # function type can be in, out or inout, represented by - + *
181 # strip function type out of each pin name
183 for i
in range(len(pingroup
)):
188 if fntype
not in '+-*':
191 fntype
= {'-': 'in', '+': 'out', '*': 'inout'}[fntype
]
192 self
.fntype
[pname
] = fntype
196 self
.pingroup
= pingroup
197 self
.gangedgroup
= gangedgrp
198 self
.bankspec
= bankspec
200 self
.origsuffix
= origsuffix
or suffix
204 # create consistent name suffixes
205 pingroup
= namesuffix(fname
, suffix
, pingroup
)
211 for name
in pingroup
[:limit
]:
213 name_
= "%s_%s" % (name
, suffix
)
216 if spec
and name
in spec
:
218 pin
= {mux
: (name_
, bank
)}
219 offs_bank
, offs_
= offs
222 idx_
+= bankspec
[bank
]
225 for name
in pingroup
:
227 name_
= "%s_%s" % (name
, suffix
)
234 idx_
, mux_
= spec
[name
]
236 pin
= {mux_
: (name_
, bank
)}
238 res
[idx_
].update(pin
)