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