add inout spec
[pinmux.git] / src / spec / interfaces.py
1 #!/usr/bin/env python
2
3 from copy import deepcopy
4
5 class Pinouts(object):
6 def __init__(self):
7 self.pins = {}
8 self.fnspec = {}
9
10 def has_key(self, k):
11 return self.pins.has_key(k)
12
13 def add_spec(self, k, v):
14 self.fnspec[k] = v
15
16 def update(self, pinidx, v):
17 if not self.pins.has_key(pinidx):
18 self.pins[pinidx] = v
19 else:
20 self.pins[pinidx].update(v)
21
22 def keys(self):
23 return self.pins.keys()
24
25 def items(self):
26 return self.pins.items()
27
28 def get(self, k):
29 return self.pins[k]
30
31 def __len__(self):
32 return len(self.pins)
33
34 def __delitem__(self, k):
35 del self.pins[k]
36
37
38 class Pins(object):
39
40 def __init__(self, fname, pingroup, bankspec, suffix, offs, bank, mux,
41 spec=None, limit=None, origsuffix=None):
42
43 # function type can be in, out or inout, represented by - + *
44 # strip function type out of each pin name
45 self.fntype = {}
46 for i in range(len(pingroup)):
47 pname = pingroup[i]
48 if not pname:
49 continue
50 fntype = pname[-1]
51 if fntype not in '+-*':
52 continue
53 pname = pname[:-1]
54 fntype = {'-': 'in', '+': 'out', '*': 'inout'}[fntype]
55 self.fntype[pname] = fntype
56 pingroup[i] = pname
57
58 self.fname = fname
59 self.pingroup = pingroup
60 self.bankspec = bankspec
61 self.suffix = suffix
62 self.origsuffix = origsuffix or suffix
63 self.bank = bank
64 self.mux = mux
65
66 # create consistent name suffixes
67 pingroup = namesuffix(fname, suffix, pingroup)
68 suffix = '' # hack
69
70 res = {}
71 names = {}
72 idx = 0
73 for name in pingroup[:limit]:
74 if suffix and name:
75 name_ = "%s_%s" % (name, suffix)
76 else:
77 name_ = name
78 if spec and spec.has_key(name):
79 continue
80 pin = {mux: (name_, bank)}
81 offs_bank, offs_ = offs
82 idx_ = offs_ + idx
83 idx += 1
84 idx_ += bankspec[bank]
85 res[idx_] = pin
86 names[name] = idx_
87 for name in pingroup:
88 if suffix and name:
89 name_ = "%s_%s" % (name, suffix)
90 else:
91 name_ = name
92 if not spec:
93 continue
94 if not spec.has_key(name):
95 continue
96 idx_, mux_, bank_ = spec[name]
97 idx_ = names[idx_]
98 pin = {mux_: (name_, bank_)}
99 if res.has_key(idx_):
100 res[idx_].update(pin)
101 else:
102 res[idx_] = pin
103
104 self.pins = res
105
106
107 def i2s(bankspec, suffix, offs, bank, mux=1, spec=None, limit=None):
108 i2spins = ['MCK+', 'BCK+', 'LRCK+', 'DI-']
109 for i in range(4):
110 i2spins.append("DO%d+" % i)
111 return Pins('IIS', i2spins, bankspec, suffix, offs, bank, mux, spec, limit,
112 origsuffix=suffix)
113
114 def emmc(bankspec, suffix, offs, bank, mux=1, spec=None):
115 emmcpins = ['CMD+', 'CLK+']
116 for i in range(8):
117 emmcpins.append("D%d*" % i)
118 return Pins('MMC', emmcpins, bankspec, suffix, offs, bank, mux, spec,
119 origsuffix=suffix)
120
121 def sdmmc(bankspec, suffix, offs, bank, mux=1, spec=None,
122 start=None, limit=None):
123 sdmmcpins = ['CMD+', 'CLK+']
124 for i in range(4):
125 sdmmcpins.append("D%d*" % i)
126 sdmmcpins = sdmmcpins[start:limit]
127 return Pins('SD', sdmmcpins, bankspec, suffix, offs, bank, mux, spec,
128 origsuffix=suffix)
129
130 def spi(bankspec, suffix, offs, bank, mux=1, spec=None):
131 spipins = ['CLK*', 'NSS*', 'MOSI*', 'MISO*']
132 return Pins('SPI', spipins, bankspec, suffix, offs, bank, mux, spec,
133 origsuffix=suffix)
134
135 def quadspi(bankspec, suffix, offs, bank, mux=1, spec=None, limit=None):
136 spipins = ['CK*', 'NSS*', 'IO0*', 'IO1*', 'IO2*', 'IO3*']
137 return Pins('QSPI', spipins, bankspec, suffix, offs, bank, mux, spec, limit,
138 origsuffix=suffix)
139
140 def i2c(bankspec, suffix, offs, bank, mux=1, spec=None):
141 spipins = ['SDA*', 'SCL*']
142 return Pins('TWI', spipins, bankspec, suffix, offs, bank, mux, spec,
143 origsuffix=suffix)
144
145 def jtag(bankspec, suffix, offs, bank, mux=1, spec=None):
146 jtagpins = ['MS+', 'DI-', 'DO+', 'CK+']
147 return Pins('JTAG', jtagpins, bankspec, suffix, offs, bank, mux, spec,
148 origsuffix=suffix)
149
150 def uart(bankspec, suffix, offs, bank, mux=1, spec=None):
151 uartpins = ['TX+', 'RX-']
152 return Pins('UART', uartpins, bankspec, suffix, offs, bank, mux, spec,
153 origsuffix=suffix)
154
155 def namesuffix(name, suffix, namelist):
156 names = []
157 for n in namelist:
158 if n:
159 names.append("%s%s_%s" % (name, suffix, n))
160 else:
161 names.append("%s_%s" % (name, suffix))
162 return names
163
164 def ulpi(bankspec, suffix, offs, bank, mux=1, spec=None):
165 ulpipins = ['CK+', 'DIR+', 'STP+', 'NXT+']
166 for i in range(8):
167 ulpipins.append('D%d*' % i)
168 return Pins('ULPI', ulpipins, bankspec, suffix, offs, bank, mux, spec,
169 origsuffix=suffix)
170
171 def uartfull(bankspec, suffix, offs, bank, mux=1, spec=None):
172 uartpins = ['TX+', 'RX-', 'CTS-', 'RTS+']
173 return Pins('UARTQ', uartpins, bankspec, suffix, offs, bank, mux, spec,
174 origsuffix=suffix)
175
176 def rgbttl(bankspec, suffix, offs, bank, mux=1, spec=None):
177 ttlpins = ['CK+', 'DE+', 'HS+', 'VS+']
178 for i in range(24):
179 ttlpins.append("D%d+" % i)
180 return Pins('LCD', ttlpins, bankspec, suffix, offs, bank, mux, spec,
181 origsuffix=suffix)
182
183 def rgmii(bankspec, suffix, offs, bank, mux=1, spec=None):
184 buspins = []
185 for i in range(4):
186 buspins.append("ERXD%d-" % i)
187 for i in range(4):
188 buspins.append("ETXD%d+" % i)
189 buspins += ['ERXCK-', 'ERXERR-', 'ERXDV-',
190 'EMDC+', 'EMDIO*',
191 'ETXEN+', 'ETXCK+', 'ECRS-',
192 'ECOL+', 'ETXERR+']
193 return Pins('RG', buspins, bankspec, suffix, offs, bank, mux, spec,
194 origsuffix=suffix)
195
196 def flexbus1(bankspec, suffix, offs, bank, mux=1, spec=None, limit=None):
197 buspins = []
198 for i in range(8):
199 buspins.append("AD%d*" % i)
200 for i in range(2):
201 buspins.append("CS%d+" % i)
202 buspins += ['ALE', 'OE', 'RW', 'TA', 'CLK+',
203 'A0', 'A1', 'TS', 'TBST',
204 'TSIZ0', 'TSIZ1']
205 for i in range(4):
206 buspins.append("BWE%d" % i)
207 for i in range(2,6):
208 buspins.append("CS%d+" % i)
209 return Pins('FB', buspins, bankspec, suffix, offs, bank, mux, spec, limit,
210 origsuffix=suffix)
211
212 def flexbus2(bankspec, suffix, offs, bank, mux=1, spec=None, limit=None):
213 buspins = []
214 for i in range(8,32):
215 buspins.append("AD%d*" % i)
216 return Pins('FB', buspins, bankspec, suffix, offs, bank, mux, spec, limit,
217 origsuffix=suffix)
218
219 def sdram1(bankspec, suffix, offs, bank, mux=1, spec=None):
220 buspins = []
221 for i in range(16):
222 buspins.append("SDRDQM%d*" % i)
223 for i in range(12):
224 buspins.append("SDRAD%d+" % i)
225 for i in range(8):
226 buspins.append("SDRDQ%d+" % i)
227 for i in range(3):
228 buspins.append("SDRCS%d#+" % i)
229 for i in range(2):
230 buspins.append("SDRDQ%d+" % i)
231 for i in range(2):
232 buspins.append("SDRBA%d+" % i)
233 buspins += ['SDRCKE+', 'SDRRAS#+', 'SDRCAS#+', 'SDRWE#+',
234 'SDRRST+']
235 return Pins('SDR', buspins, bankspec, suffix, offs, bank, mux, spec,
236 origsuffix=suffix)
237
238 def sdram2(bankspec, suffix, offs, bank, mux=1, spec=None, limit=None):
239 buspins = []
240 for i in range(3,6):
241 buspins.append("SDRCS%d#+" % i)
242 for i in range(8,32):
243 buspins.append("SDRDQ%d*" % i)
244 return Pins('SDR', buspins, bankspec, suffix, offs, bank, mux, spec, limit,
245 origsuffix=suffix)
246
247 def mcu8080(bankspec, suffix, offs, bank, mux=1, spec=None):
248 buspins = []
249 for i in range(8):
250 buspins.append("MCUD%d*" % i)
251 for i in range(8):
252 buspins.append("MCUAD%d+" % (i+8))
253 for i in range(6):
254 buspins.append("MCUCS%d+" % i)
255 for i in range(2):
256 buspins.append("MCUNRB%d+" % i)
257 buspins += ['MCUCD+', 'MCURD+', 'MCUWR+', 'MCUCLE+', 'MCUALE+',
258 'MCURST+']
259 return Pins('MCU', buspins, bankspec, suffix, offs, bank, mux, spec,
260 origsuffix=suffix)
261
262 def _pinbank(bankspec, prefix, suffix, offs, bank, gpiooffs, gpionum=1, mux=1,
263 spec=None):
264 gpiopins = []
265 for i in range(gpiooffs, gpiooffs+gpionum):
266 gpiopins.append("%s%d*" % (bank, i))
267 return Pins('GPIO', gpiopins, bankspec, suffix, offs, bank, mux, spec,
268 origsuffix=suffix)
269
270 def eint(bankspec, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None):
271 gpiopins = []
272 for i in range(gpiooffs, gpiooffs+gpionum):
273 gpiopins.append("%d*" % (i))
274 return Pins('EINT', gpiopins, bankspec, suffix, offs, bank, mux, spec,
275 origsuffix=suffix)
276
277 def pwm(bankspec, suffix, offs, bank, mux=1, spec=None):
278 return Pins('PWM', ['+', ], bankspec, suffix, offs, bank, mux, spec,
279 origsuffix=suffix)
280
281 def gpio(bankspec, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None):
282 return _pinbank(bankspec, "GPIO", suffix, offs, bank, gpiooffs,
283 gpionum, mux=0, spec=None)
284
285 def display(pins):
286 print "| Pin | Mux0 | Mux1 | Mux2 | Mux3 |"
287 print "| --- | ----------- | ----------- | ----------- | ----------- |"
288 pinidx = pins.keys()
289 pinidx.sort()
290 for pin in pinidx:
291 pdata = pins.get(pin)
292 res = '| %3d |' % pin
293 for mux in range(4):
294 if not pdata.has_key(mux):
295 res += " |"
296 continue
297 name, bank = pdata[mux]
298 res += " %s %-9s |" % (bank, name)
299 print res
300
301 def fnsplit(f):
302 a = ''
303 n = 0
304 if not f.startswith('FB_'):
305 f2 = f.split('_')
306 if len(f2) == 2:
307 if f2[1].isdigit():
308 return f2[0], int(f2[1])
309 return f2[0], f2[1]
310 #print f
311 while f and not f[0].isdigit():
312 a += f[0]
313 f = f[1:]
314 return a, int(f) if f else None
315
316 def fnsort(f1, f2):
317 a1, n1 = fnsplit(f1)
318 a2, n2 = fnsplit(f2)
319 x = cmp(a1, a2)
320 if x != 0:
321 return x
322 return cmp(n1, n2)
323
324 def find_fn(fname, names):
325 for n in names:
326 if fname.startswith(n):
327 return n
328
329 def display_fns(bankspec, pins, function_names):
330 fn_names = function_names.keys()
331 fns = {}
332 for (pin, pdata) in pins.items():
333 for mux in range(1,4): # skip GPIO for now
334 if not pdata.has_key(mux):
335 continue
336 name, bank = pdata[mux]
337 assert name != None, str(bank)
338 if not fns.has_key(name):
339 fns[name] = []
340 fns[name].append((pin-bankspec[bank], mux, bank))
341
342 fnidx = fns.keys()
343 fnidx.sort(fnsort)
344 current_fn = None
345 for fname in fnidx:
346 fnbase = find_fn(fname, fn_names)
347 #print "name", fname, fnbase
348 if fnbase != current_fn:
349 if current_fn is not None:
350 print
351 print "## %s" % fnbase
352 print
353 print function_names[fnbase]
354 print
355 current_fn = fnbase
356 print "* %-9s :" % fname,
357 for (pin, mux, bank) in fns[fname]:
358 print "%s%d/%d" % (bank, pin, mux),
359 print
360
361 return fns
362
363 def check_functions(title, bankspec, fns, pins, required, eint, pwm,
364 descriptions=None):
365 fns = deepcopy(fns)
366 pins = deepcopy(pins)
367 if descriptions is None:
368 descriptions = {}
369
370 print "# Pinmap for %s" % title
371 print
372
373
374 for name in required:
375 print "## %s" % name
376 print
377 if descriptions and descriptions.has_key(name):
378 print descriptions[name]
379 print
380
381 name = name.split(':')
382 if len(name) == 2:
383 findbank = name[0][0]
384 findmux = int(name[0][1:])
385 name = name[1]
386 else:
387 name = name[0]
388 findbank = None
389 findmux = None
390 name = name.split('/')
391 if len(name) == 2:
392 count = int(name[1])
393 else:
394 count = 100000
395 name = name[0]
396 found = set()
397 fnidx = fns.keys()
398 #fnidx.sort(fnsort)
399 pinfound = {}
400 for fname in fnidx:
401 if not fname.startswith(name):
402 continue
403 for pin, mux, bank in fns[fname]:
404 if findbank is not None:
405 if findbank != bank:
406 continue
407 if findmux != mux:
408 continue
409 pin_ = pin + bankspec[bank]
410 if pins.has_key(pin_):
411 pinfound[pin_] = (fname, pin_, bank, pin, mux)
412
413 pinidx = pinfound.keys()
414 pinidx.sort()
415
416 for pin_ in pinidx:
417 fname, pin_, bank, pin, mux = pinfound[pin_]
418 if fname in found:
419 continue
420 found.add(fname)
421 if len(found) > count:
422 continue
423 del pins[pin_]
424 print "* %s %d %s%d/%d" % (fname, pin_, bank, pin, mux)
425
426 print
427
428 # gpios
429 gpios = []
430 for name in descriptions.keys():
431 if not name.startswith('GPIO'):
432 continue
433 if name == 'GPIO':
434 continue
435 gpios.append(name)
436 gpios.sort()
437
438 if gpios:
439 print "## GPIO"
440 print
441
442 for fname in gpios:
443 if fname in found:
444 continue
445 desc = ''
446 if descriptions and descriptions.has_key(fname):
447 desc = ': %s' % descriptions[fname]
448 bank = fname[4]
449 pin = int(fname[5:])
450 pin_ = pin + bankspec[bank]
451 if not pins.has_key(pin_):
452 continue
453 del pins[pin_]
454 found.add(fname)
455 print "* %-8s %d %s%-2d %s" % (fname, pin_, bank, pin, desc)
456 print
457
458 if eint:
459 display_group(bankspec, "EINT", eint, fns, pins, descriptions)
460 if pwm:
461 display_group(bankspec, "PWM", pwm, fns, pins, descriptions)
462
463 print "## Unused Pinouts (spare as GPIO) for '%s'" % title
464 print
465 if descriptions and descriptions.has_key('GPIO'):
466 print descriptions['GPIO']
467 print
468 display(pins)
469 print
470
471 return pins # unused
472
473 def display_group(bankspec, title, todisplay, fns, pins, descriptions):
474 print "## %s" % title
475 print
476
477 found = set()
478 for fname in todisplay:
479 desc = ''
480 if descriptions and descriptions.has_key(fname):
481 desc = ': %s' % descriptions[fname]
482 fname = fname.split(':')
483 if len(fname) == 2:
484 findbank = fname[0][0]
485 findmux = int(fname[0][1:])
486 fname = fname[1]
487 else:
488 fname = fname[0]
489 findbank = None
490 findmux = None
491 for (pin, mux, bank) in fns[fname]:
492 if findbank is not None:
493 if findbank != bank:
494 continue
495 if findmux != mux:
496 continue
497 if fname in found:
498 continue
499 pin_ = pin + bankspec[bank]
500 if not pins.has_key(pin_):
501 continue
502 del pins[pin_]
503 found.add(fname)
504 print "* %s %d %s%d/%d %s" % (fname, pin_, bank, pin, mux, desc)
505 print
506
507 def pinmerge(pins, fn):
508 # hack, store the function specs in the pins dict
509 fname = fn.fname
510 suffix = fn.origsuffix
511 bank = fn.bank
512
513 if not hasattr(pins, 'fnspec'):
514 pins.fnspec = pins
515 if fname == 'GPIO':
516 fname = fname + bank
517 assert not pins.has_key('EINT')
518 if not pins.fnspec.has_key(fname):
519 pins.add_spec(fname, {})
520 print "fname bank suffix", fname, bank, suffix
521 if suffix or fname == 'EINT' or fname == 'PWM':
522 specname = fname + suffix
523 else:
524 specname = fname + bank
525 pins.fnspec[fname][specname] = fn
526
527
528 # merge actual pins
529 for (pinidx, v) in fn.pins.items():
530 print "pinidx", pinidx
531 pins.update(pinidx, v)
532
533 def display_fixed(fixed, offs):
534
535 fkeys = fixed.keys()
536 fkeys.sort()
537 pin_ = offs
538 for pin, k in enumerate(fkeys):
539 print "## %s" % k
540 print
541 prevname = ''
542 linecount = 0
543 for name in fixed[k]:
544 if linecount == 4:
545 linecount = 0
546 print
547 if prevname[:2] == name[:2] and linecount != 0:
548 print name,
549 linecount += 1
550 else:
551 if linecount != 0:
552 print
553 print "* %d: %d %s" % (pin_, pin, name),
554 linecount = 1
555 prevname = name
556 pin_ += 1
557 if linecount != 0:
558 print
559 print
560