check pin position overwriting
[pinmux.git] / src / spec / interfaces.py
1 #!/usr/bin/env python
2
3 from copy import deepcopy
4
5
6 def namesuffix(name, suffix, namelist):
7 names = []
8 for n in namelist:
9 if n:
10 names.append("%s%s_%s" % (name, suffix, n))
11 else:
12 names.append("%s_%s" % (name, suffix))
13 return names
14
15
16 class Pinouts(object):
17 def __init__(self, bankspec):
18 self.bankspec = bankspec
19 self.pins = {}
20 self.fnspec = {}
21
22 def __contains__(self, k):
23 return k in self.pins
24
25 def has_key(self, k):
26 return k in self.pins
27
28 def add_spec(self, k, v):
29 self.fnspec[k] = v
30
31 def update(self, pinidx, v):
32 if pinidx not in self.pins:
33 self.pins[pinidx] = v
34 else:
35 for k in v:
36 assert k not in self.pins[pinidx], \
37 "pin %d position %d already taken\n%s\n%s" % \
38 (pinidx, k, str(v), self.pins[pinidx])
39 self.pins[pinidx].update(v)
40
41 def keys(self):
42 return self.pins.keys()
43
44 def items(self):
45 return self.pins.items()
46
47 def get(self, k):
48 return self.pins[k]
49
50 def __len__(self):
51 return len(self.pins)
52
53 def __delitem__(self, k):
54 del self.pins[k]
55
56 def __getitem__(self, k):
57 return self.pins[k]
58
59 def i2s(self, suffix, offs, bank, mux=1, spec=None, limit=None):
60 i2spins = ['MCK+', 'BCK+', 'LRCK+', 'DI-', 'DO+']
61 # for i in range(4):
62 # i2spins.append("DO%d+" % i)
63 pins = Pins('IIS', i2spins, self.bankspec,
64 suffix, offs, bank, mux,
65 spec, limit, origsuffix=suffix)
66 self.pinmerge(pins)
67
68 def emmc(self, suffix, offs, bank, mux=1, spec=None):
69 emmcpins = ['CMD+', 'CLK+']
70 for i in range(8):
71 emmcpins.append("D%d*" % i)
72 pins = Pins('MMC', emmcpins, self.bankspec,
73 suffix, offs, bank, mux,
74 spec, origsuffix=suffix)
75 self.pinmerge(pins)
76
77 def sdmmc(self, suffix, offs, bank, mux=1, spec=None,
78 start=None, limit=None):
79 sdmmcpins = ['CMD+', 'CLK+']
80 for i in range(4):
81 sdmmcpins.append("D%d*" % i)
82 sdmmcpins = sdmmcpins[start:limit]
83 pins = Pins('SD', sdmmcpins, self.bankspec,
84 suffix, offs, bank, mux,
85 spec, origsuffix=suffix)
86 self.pinmerge(pins)
87
88 def spi(self, suffix, offs, bank, mux=1, spec=None):
89 spipins = ['CLK*', 'NSS*', 'MOSI*', 'MISO*']
90 pins = Pins('SPI', spipins, self.bankspec,
91 suffix, offs, bank, mux,
92 spec, origsuffix=suffix)
93 self.pinmerge(pins)
94
95 def quadspi(self, suffix, offs, bank, mux=1, spec=None, limit=None):
96 spipins = ['CK*', 'NSS*', 'IO0*', 'IO1*', 'IO2*', 'IO3*']
97 pins = Pins('QSPI', spipins, self.bankspec,
98 suffix, offs, bank, mux,
99 spec, limit, origsuffix=suffix)
100 self.pinmerge(pins)
101
102 def i2c(self, suffix, offs, bank, mux=1, spec=None):
103 spipins = ['SDA*', 'SCL*']
104 pins = Pins('TWI', spipins, self.bankspec,
105 suffix, offs, bank, mux,
106 spec, origsuffix=suffix)
107 self.pinmerge(pins)
108
109 def jtag(self, suffix, offs, bank, mux=1, spec=None):
110 jtagpins = ['MS+', 'DI-', 'DO+', 'CK+']
111 pins = Pins('JTAG', jtagpins, self.bankspec,
112 suffix, offs, bank, mux,
113 spec, origsuffix=suffix)
114 self.pinmerge(pins)
115
116 def uart(self, suffix, offs, bank, mux=1, spec=None):
117 uartpins = ['TX+', 'RX-']
118 pins = Pins('UART', uartpins, self.bankspec,
119 suffix, offs, bank, mux,
120 spec, origsuffix=suffix)
121 self.pinmerge(pins)
122
123 def ulpi(self, suffix, offs, bank, mux=1, spec=None):
124 ulpipins = ['CK+', 'DIR+', 'STP+', 'NXT+']
125 for i in range(8):
126 ulpipins.append('D%d*' % i)
127 pins = Pins('ULPI', ulpipins, self.bankspec,
128 suffix, offs, bank, mux,
129 spec, origsuffix=suffix)
130 self.pinmerge(pins)
131
132 def uartfull(self, suffix, offs, bank, mux=1, spec=None):
133 uartpins = ['TX+', 'RX-', 'CTS-', 'RTS+']
134 pins = Pins('UARTQ', uartpins, self.bankspec,
135 suffix, offs, bank, mux,
136 spec, origsuffix=suffix)
137 self.pinmerge(pins)
138
139 def rgbttl(self, suffix, offs, bank, mux=1, spec=None):
140 ttlpins = ['CK+', 'DE+', 'HS+', 'VS+']
141 for i in range(24):
142 ttlpins.append("D%d+" % i)
143 pins = Pins('LCD', ttlpins, self.bankspec,
144 suffix, offs, bank, mux,
145 spec, origsuffix=suffix)
146 self.pinmerge(pins)
147
148 def rgmii(self, suffix, offs, bank, mux=1, spec=None):
149 buspins = []
150 for i in range(4):
151 buspins.append("ERXD%d-" % i)
152 for i in range(4):
153 buspins.append("ETXD%d+" % i)
154 buspins += ['ERXCK-', 'ERXERR-', 'ERXDV-',
155 'EMDC+', 'EMDIO*',
156 'ETXEN+', 'ETXCK+', 'ECRS-',
157 'ECOL+', 'ETXERR+']
158 pins = Pins('RG', buspins, self.bankspec,
159 suffix, offs, bank, mux,
160 spec, origsuffix=suffix)
161 self.pinmerge(pins)
162
163 def flexbus1(self, suffix, offs, bank, mux=1, spec=None, limit=None):
164 buspins = []
165 for i in range(8):
166 buspins.append("AD%d*" % i)
167 for i in range(2):
168 buspins.append("CS%d+" % i)
169 buspins += ['ALE', 'OE', 'RW', 'TA', 'CLK+',
170 'A0', 'A1', 'TS', 'TBST',
171 'TSIZ0', 'TSIZ1']
172 for i in range(4):
173 buspins.append("BWE%d" % i)
174 for i in range(2, 6):
175 buspins.append("CS%d+" % i)
176 pins = Pins('FB', buspins, self.bankspec,
177 suffix, offs, bank, mux,
178 spec, limit, origsuffix=suffix)
179 self.pinmerge(pins)
180
181 def flexbus2(self, suffix, offs, bank, mux=1, spec=None, limit=None):
182 buspins = []
183 for i in range(8, 32):
184 buspins.append("AD%d*" % i)
185 pins = Pins('FB', buspins, self.bankspec,
186 suffix, offs, bank, mux,
187 spec, limit, origsuffix=suffix)
188 self.pinmerge(pins)
189
190 def sdram1(self, suffix, offs, bank, mux=1, spec=None):
191 buspins = []
192 for i in range(16):
193 buspins.append("SDRDQM%d*" % i)
194 for i in range(12):
195 buspins.append("SDRAD%d+" % i)
196 for i in range(8):
197 buspins.append("SDRDQ%d+" % i)
198 for i in range(3):
199 buspins.append("SDRCS%d#+" % i)
200 for i in range(2):
201 buspins.append("SDRDQ%d+" % i)
202 for i in range(2):
203 buspins.append("SDRBA%d+" % i)
204 buspins += ['SDRCKE+', 'SDRRAS#+', 'SDRCAS#+', 'SDRWE#+',
205 'SDRRST+']
206 pins = Pins('SDR', buspins, self.bankspec,
207 suffix, offs, bank, mux,
208 spec, origsuffix=suffix)
209 self.pinmerge(pins)
210
211 def sdram2(self, suffix, offs, bank, mux=1, spec=None, limit=None):
212 buspins = []
213 for i in range(3, 6):
214 buspins.append("SDRCS%d#+" % i)
215 for i in range(8, 32):
216 buspins.append("SDRDQ%d*" % i)
217 pins = Pins('SDR', buspins, self.bankspec,
218 suffix, offs, bank, mux,
219 spec, limit, origsuffix=suffix)
220 self.pinmerge(pins)
221
222 def mcu8080(self, suffix, offs, bank, mux=1, spec=None):
223 buspins = []
224 for i in range(8):
225 buspins.append("MCUD%d*" % i)
226 for i in range(8):
227 buspins.append("MCUAD%d+" % (i + 8))
228 for i in range(6):
229 buspins.append("MCUCS%d+" % i)
230 for i in range(2):
231 buspins.append("MCUNRB%d+" % i)
232 buspins += ['MCUCD+', 'MCURD+', 'MCUWR+', 'MCUCLE+', 'MCUALE+',
233 'MCURST+']
234 pins = Pins('MCU', buspins, self.bankspec,
235 suffix, offs, bank, mux,
236 spec, origsuffix=suffix)
237 self.pinmerge(pins)
238
239 def _pinbank(self, prefix, suffix, offs, bank, gpiooffs, gpionum=1, mux=1,
240 spec=None):
241 gpiopins = []
242 for i in range(gpiooffs, gpiooffs + gpionum):
243 gpiopins.append("%s%d*" % (bank, i))
244 pins = Pins(prefix, gpiopins, self.bankspec,
245 suffix, offs, bank, mux,
246 spec, origsuffix=suffix)
247 self.pinmerge(pins)
248
249 def eint(self, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None):
250 gpiopins = []
251 for i in range(gpiooffs, gpiooffs + gpionum):
252 gpiopins.append("%d*" % (i))
253 pins = Pins('EINT', gpiopins, self.bankspec,
254 suffix, offs, bank, mux,
255 spec, origsuffix=suffix)
256 self.pinmerge(pins)
257
258 def pwm(self, suffix, offs, bank, pwmoffs, pwmnum=1, mux=1, spec=None):
259 pwmpins = []
260 for i in range(pwmoffs, pwmoffs + pwmnum):
261 pwmpins.append("%d+" % (i))
262 pins = Pins('PWM', pwmpins, self.bankspec,
263 suffix, offs, bank, mux,
264 spec, origsuffix=suffix)
265 self.pinmerge(pins)
266
267 def gpio(self, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None):
268 self._pinbank("GPIO%s" % bank, suffix, offs, bank, gpiooffs,
269 gpionum, mux=0, spec=None)
270
271 def pinmerge(self, fn):
272 # hack, store the function specs in the pins dict
273 fname = fn.fname
274 suffix = fn.origsuffix
275 bank = fn.bank
276
277 if not hasattr(self, 'fnspec'):
278 self.fnspec = pins
279 if fname == 'GPIO':
280 fname = fname + bank
281 assert 'EINT' not in self
282 if fname not in self.fnspec:
283 self.add_spec(fname, {})
284 if suffix or fname == 'EINT' or fname == 'PWM':
285 specname = fname + suffix
286 else:
287 specname = fname
288 #print "fname bank specname suffix ", fname, bank, specname, repr(
289 # suffix)
290 if specname in self.fnspec[fname]:
291 # ok so some declarations may bring in different
292 # names at different stages (EINT, PWM, flexbus1/2)
293 # so we have to merge the names in. main thing is
294 # the pingroup
295 tomerge = self.fnspec[fname][specname]
296 for p in fn.pingroup:
297 if p not in tomerge.pingroup:
298 tomerge.pingroup.append(p)
299 tomerge.pins.update(fn.pins)
300 tomerge.fntype.update(fn.fntype)
301 else:
302 self.fnspec[fname][specname] = deepcopy(fn)
303
304 # merge actual pins
305 for (pinidx, v) in fn.pins.items():
306 self.update(pinidx, v)
307
308
309 class Pins(object):
310
311 def __init__(self, fname, pingroup, bankspec, suffix, offs, bank, mux,
312 spec=None, limit=None, origsuffix=None):
313
314 # function type can be in, out or inout, represented by - + *
315 # strip function type out of each pin name
316 self.fntype = {}
317 for i in range(len(pingroup)):
318 pname = pingroup[i]
319 if not pname:
320 continue
321 fntype = pname[-1]
322 if fntype not in '+-*':
323 continue
324 pname = pname[:-1]
325 fntype = {'-': 'in', '+': 'out', '*': 'inout'}[fntype]
326 self.fntype[pname] = fntype
327 pingroup[i] = pname
328
329 self.fname = fname
330 self.pingroup = pingroup
331 self.bankspec = bankspec
332 self.suffix = suffix
333 self.origsuffix = origsuffix or suffix
334 self.bank = bank
335 self.mux = mux
336
337 # create consistent name suffixes
338 pingroup = namesuffix(fname, suffix, pingroup)
339 suffix = '' # hack
340
341 res = {}
342 names = {}
343 idx = 0
344 for name in pingroup[:limit]:
345 if suffix and name:
346 name_ = "%s_%s" % (name, suffix)
347 else:
348 name_ = name
349 if spec and name in spec:
350 continue
351 pin = {mux: (name_, bank)}
352 offs_bank, offs_ = offs
353 idx_ = offs_ + idx
354 idx += 1
355 idx_ += bankspec[bank]
356 res[idx_] = pin
357 names[name] = idx_
358 for name in pingroup:
359 if suffix and name:
360 name_ = "%s_%s" % (name, suffix)
361 else:
362 name_ = name
363 if not spec:
364 continue
365 if name not in spec:
366 continue
367 idx_, mux_, bank_ = spec[name]
368 idx_ = names[idx_]
369 pin = {mux_: (name_, bank_)}
370 if idx_ in res:
371 res[idx_].update(pin)
372 else:
373 res[idx_] = pin
374
375 self.pins = res