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