c57a07683352f7170992080479c431592474cb46
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 self
.pinouts
.pinmerge(pins
)
81 class Pinouts(object):
82 def __init__(self
, bankspec
):
83 self
.bankspec
= bankspec
86 for fname
, pinfn
in pinspec
:
87 if isinstance(pinfn
, tuple):
91 setattr(self
, name
, PinGen(self
, fname
, pinfn
, self
.bankspec
))
93 def __contains__(self
, k
):
99 def add_spec(self
, k
, v
):
102 def update(self
, pinidx
, v
):
103 if pinidx
not in self
.pins
:
104 self
.pins
[pinidx
] = v
107 assert k
not in self
.pins
[pinidx
], \
108 "pin %d position %d already taken\n%s\n%s" % \
109 (pinidx
, k
, str(v
), self
.pins
[pinidx
])
110 self
.pins
[pinidx
].update(v
)
113 return self
.pins
.keys()
116 return self
.pins
.items()
122 return len(self
.pins
)
124 def __delitem__(self
, k
):
127 def __getitem__(self
, k
):
130 def pinmerge(self
, fn
):
131 # hack, store the function specs in the pins dict
133 suffix
= fn
.origsuffix
136 if not hasattr(self
, 'fnspec'):
140 assert 'EINT' not in self
141 if fname
not in self
.fnspec
:
142 self
.add_spec(fname
, {})
143 if suffix
or fname
== 'EINT' or fname
== 'PWM':
144 specname
= fname
+ suffix
147 # print "fname bank specname suffix ", fname, bank, specname, repr(
149 if specname
in self
.fnspec
[fname
]:
150 # ok so some declarations may bring in different
151 # names at different stages (EINT, PWM, flexbus1/2)
152 # so we have to merge the names in. main thing is
154 tomerge
= self
.fnspec
[fname
][specname
]
155 for p
in fn
.pingroup
:
156 if p
not in tomerge
.pingroup
:
157 tomerge
.pingroup
.append(p
)
158 tomerge
.pins
.update(fn
.pins
)
159 tomerge
.fntype
.update(fn
.fntype
)
161 self
.fnspec
[fname
][specname
] = deepcopy(fn
)
164 for (pinidx
, v
) in fn
.pins
.items():
165 self
.update(pinidx
, v
)
170 def __init__(self
, fname
, pingroup
, bankspec
, suffix
, offs
, bank
, mux
,
171 spec
=None, limit
=None, origsuffix
=None, gangedgrp
=None):
173 # function type can be in, out or inout, represented by - + *
174 # strip function type out of each pin name
176 for i
in range(len(pingroup
)):
181 if fntype
not in '+-*':
184 fntype
= {'-': 'in', '+': 'out', '*': 'inout'}[fntype
]
185 self
.fntype
[pname
] = fntype
189 self
.pingroup
= pingroup
190 self
.gangedgroup
= gangedgrp
191 self
.bankspec
= bankspec
193 self
.origsuffix
= origsuffix
or suffix
197 # create consistent name suffixes
198 pingroup
= namesuffix(fname
, suffix
, pingroup
)
204 for name
in pingroup
[:limit
]:
206 name_
= "%s_%s" % (name
, suffix
)
209 if spec
and name
in spec
:
211 pin
= {mux
: (name_
, bank
)}
212 offs_bank
, offs_
= offs
215 idx_
+= bankspec
[bank
]
218 for name
in pingroup
:
220 name_
= "%s_%s" % (name
, suffix
)
227 idx_
, mux_
= spec
[name
]
229 pin
= {mux_
: (name_
, bank
)}
231 res
[idx_
].update(pin
)