X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fspec%2Finterfaces.py;h=f5ecf4817ba439b607a1909a4fcb6aa2589e2afd;hb=b98e51ea2806517b0ac5fd707ae65f1c878500fa;hp=92f0c224ad07bcd37ada997f3cf8d66dac2a2bc7;hpb=1c451a11c4b49793e9fb057e7263d2657fe735ca;p=pinmux.git diff --git a/src/spec/interfaces.py b/src/spec/interfaces.py index 92f0c22..f5ecf48 100644 --- a/src/spec/interfaces.py +++ b/src/spec/interfaces.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from spec.pinfunctions import pinspec from copy import deepcopy @@ -14,111 +15,110 @@ def namesuffix(name, suffix, namelist): class PinGen(object): + """ a meta-helper which creates pins from the pinspec + and adds them to the pinouts. + + __call__ is used to effectively create a lambda function, which + in combination with setattr (below) gives the function a name + in the Pinouts class, according to the pinspec. + + arguments to __call__ (which ends up as Pinouts.i2s, Pinouts.sdmmc + and so on, according to spec.pinfunctions.pinspec) are: + + suffix: e.g. GPIO or SD or SPI + offs : a tuple of (Bank, Bank offset) as a string, integer + mux : which column in the multiplexer + start : the start of a subset of pins to be inserted + limit : the end of the subset (or the number if start also given) + spec : *EXTRA* pins to be inserted (at different implicit positions) + + the pins are inserted with the suffix, starting from the + offset position using offs as the row and mux as the column, + and working in a constant increment down the rows. + + spec is slightly complicated, basically there's extra + functions that we want to be on the same pin (but a different mux) + because their use is mutually-exclusive. without this spec + argument the extra pins would need to be MANUALLY moved about + during the development of the pinmux, if the "main" pins + were also moved about. this would be a pain. + + so instead, extra pins are given of the form: + { 'EXTRA1' : ('PREEXISTING_NAME', MUX_COLUMN), + ... + } + + where the function EXTRA1 will always be placed on the SAME ROW + as PREEXISTING_NAME, just in MUX_COLUMN. this may be done + several times i.e. multiple new EXTRA functions can be added + on the same row as PRE_EXISTING_NAME, just with different + MUX_COLUMN values. + + Note: spec must implicitly be in the same Bank. + """ + def __init__(self, pinouts, fname, pinfn, bankspec): self.pinouts = pinouts self.bankspec = bankspec self.pinfn = pinfn self.fname = fname - def __call__(self, suffix, offs, bank, mux, - spec=None, start=None, limit=None, origsuffix=None): - pingroup = self.pinfn(suffix, bank) - pingroup = pingroup[start:limit] - pins = Pins(self.fname, pingroup, self.bankspec, + def __call__(self, suffix, offs, mux, + start=None, limit=None, spec=None, origsuffix=None, + rev=False): + bank = offs[0] + pf = self.pinfn(suffix, bank) + print ("pf", suffix, bank, pf) + pingroup, gangedgroup, clock = pf + if clock: + self.pinouts.clocks[self.fname] = clock + if isinstance(pingroup, tuple): + prefix, pingroup = pingroup + else: + prefix = self.fname + if start and limit: # limit turns into an offset from start + limit = start + limit + sk = "%s:%s" % (self.fname, str(suffix)) + print ("pingroup pre", sk, pingroup) + pingroup = pingroup[start:limit] # see comment in spec.pinfunctions + if rev: + # reverse order of pingroup + pingroup.reverse() + print ("pingroup post", sk, pingroup) + if sk in self.pinouts.byspec: + self.pinouts.byspec[sk] += pingroup + else: + self.pinouts.byspec[sk] = deepcopy(pingroup) + pins = Pins(prefix, pingroup, self.bankspec, suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinouts.pinmerge(pins) - - -# define functions here - -def i2s(suffix, bank): - return ['MCK+', 'BCK+', 'LRCK+', 'DI-', 'DO+'] - -def emmc(suffix, bank): - emmcpins = ['CMD+', 'CLK+'] - for i in range(8): - emmcpins.append("D%d*" % i) - return emmcpins - -def sdmmc(suffix, bank): - sdmmcpins = ['CMD+', 'CLK+'] - for i in range(4): - sdmmcpins.append("D%d*" % i) - return sdmmcpins - -def spi(suffix, bank): - return ['CLK*', 'NSS*', 'MOSI*', 'MISO*'] - -def quadspi(suffix, bank): - return ['CK*', 'NSS*', 'IO0*', 'IO1*', 'IO2*', 'IO3*'] - -def i2c(suffix, bank): - return ['SDA*', 'SCL*'] - -def jtag(suffix, bank): - return ['MS+', 'DI-', 'DO+', 'CK+'] - -def uart(suffix, bank): - return ['TX+', 'RX-'] - -def ulpi(suffix, bank): - ulpipins = ['CK+', 'DIR+', 'STP+', 'NXT+'] - for i in range(8): - ulpipins.append('D%d*' % i) - return ulpipins - -def uartfull(suffix, bank): - return ['TX+', 'RX-', 'CTS-', 'RTS+'] - -def rgbttl(suffix, bank): - ttlpins = ['CK+', 'DE+', 'HS+', 'VS+'] - for i in range(24): - ttlpins.append("D%d+" % i) - return ttlpins - -def rgmii(suffix, bank): - buspins = [] - for i in range(4): - buspins.append("ERXD%d-" % i) - for i in range(4): - buspins.append("ETXD%d+" % i) - buspins += ['ERXCK-', 'ERXERR-', 'ERXDV-', - 'EMDC+', 'EMDIO*', - 'ETXEN+', 'ETXCK+', 'ECRS-', - 'ECOL+', 'ETXERR+'] - return buspins - - -# list functions by name here - -pinspec = {'IIS': i2s, - 'MMC': emmc, - 'SD': sdmmc, - 'SPI': spi, - 'QSPI': quadspi, - 'TWI': i2c, - 'JTAG': jtag, - 'UART': uart, - 'UARTQ': uartfull, - 'LCD': rgbttl, - 'ULPI': ulpi, - 'RG': rgmii, - } + spec, origsuffix=suffix, gangedgrp=gangedgroup) + fname = self.pinouts.pinmerge(pins) + self.pinouts.setganged(fname, gangedgroup) # pinouts class + class Pinouts(object): def __init__(self, bankspec): self.bankspec = bankspec self.pins = {} self.fnspec = {} - for fname, pinfn in pinspec.items(): + self.ganged = {} + self.clocks = {} + self.byspec = {} + for fname, pinfn in pinspec: if isinstance(pinfn, tuple): name, pinfn = pinfn else: name = pinfn.__name__ - setattr(self, name, PinGen(self, fname, pinfn, self.bankspec)) + pin = PinGen(self, fname, pinfn, self.bankspec) + setattr(self, name, pin) + + def setganged(self, fname, grp): + grp = map(lambda x: x[:-1], grp) + if fname not in self.ganged: + self.ganged[fname] = [] + self.ganged[fname] += grp def __contains__(self, k): return k in self.pins @@ -136,7 +136,7 @@ class Pinouts(object): for k in v: assert k not in self.pins[pinidx], \ "pin %d position %d already taken\n%s\n%s" % \ - (pinidx, k, str(v), self.pins[pinidx]) + (pinidx, k, str(v), self.pins[pinidx]) self.pins[pinidx].update(v) def keys(self): @@ -157,110 +157,6 @@ class Pinouts(object): def __getitem__(self, k): return self.pins[k] - def flexbus1(self, suffix, offs, bank, mux=1, spec=None, limit=None): - buspins = [] - for i in range(8): - buspins.append("AD%d*" % i) - for i in range(2): - buspins.append("CS%d+" % i) - buspins += ['ALE', 'OE', 'RW', 'TA', 'CLK+', - 'A0', 'A1', 'TS', 'TBST', - 'TSIZ0', 'TSIZ1'] - for i in range(4): - buspins.append("BWE%d" % i) - for i in range(2, 6): - buspins.append("CS%d+" % i) - pins = Pins('FB', buspins, self.bankspec, - suffix, offs, bank, mux, - spec, limit, origsuffix=suffix) - self.pinmerge(pins) - - def flexbus2(self, suffix, offs, bank, mux=1, spec=None, limit=None): - buspins = [] - for i in range(8, 32): - buspins.append("AD%d*" % i) - pins = Pins('FB', buspins, self.bankspec, - suffix, offs, bank, mux, - spec, limit, origsuffix=suffix) - self.pinmerge(pins) - - def sdram1(self, suffix, offs, bank, mux=1, spec=None): - buspins = [] - for i in range(16): - buspins.append("SDRDQM%d*" % i) - for i in range(12): - buspins.append("SDRAD%d+" % i) - for i in range(8): - buspins.append("SDRDQ%d+" % i) - for i in range(3): - buspins.append("SDRCS%d#+" % i) - for i in range(2): - buspins.append("SDRDQ%d+" % i) - for i in range(2): - buspins.append("SDRBA%d+" % i) - buspins += ['SDRCKE+', 'SDRRAS#+', 'SDRCAS#+', 'SDRWE#+', - 'SDRRST+'] - pins = Pins('SDR', buspins, self.bankspec, - suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinmerge(pins) - - def sdram2(self, suffix, offs, bank, mux=1, spec=None, limit=None): - buspins = [] - for i in range(3, 6): - buspins.append("SDRCS%d#+" % i) - for i in range(8, 32): - buspins.append("SDRDQ%d*" % i) - pins = Pins('SDR', buspins, self.bankspec, - suffix, offs, bank, mux, - spec, limit, origsuffix=suffix) - self.pinmerge(pins) - - def mcu8080(self, suffix, offs, bank, mux=1, spec=None): - buspins = [] - for i in range(8): - buspins.append("MCUD%d*" % i) - for i in range(8): - buspins.append("MCUAD%d+" % (i + 8)) - for i in range(6): - buspins.append("MCUCS%d+" % i) - for i in range(2): - buspins.append("MCUNRB%d+" % i) - buspins += ['MCUCD+', 'MCURD+', 'MCUWR+', 'MCUCLE+', 'MCUALE+', - 'MCURST+'] - pins = Pins('MCU', buspins, self.bankspec, - suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinmerge(pins) - - def eint(self, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None): - gpiopins = [] - for i in range(gpiooffs, gpiooffs + gpionum): - gpiopins.append("%d*" % (i)) - pins = Pins('EINT', gpiopins, self.bankspec, - suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinmerge(pins) - - def pwm(self, suffix, offs, bank, pwmoffs, pwmnum=1, mux=1, spec=None): - pwmpins = [] - for i in range(pwmoffs, pwmoffs + pwmnum): - pwmpins.append("%d+" % (i)) - pins = Pins('PWM', pwmpins, self.bankspec, - suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinmerge(pins) - - def gpio(self, suffix, offs, bank, gpiooffs, gpionum=1, mux=1, spec=None): - prefix = "GPIO%s" % bank - gpiopins = [] - for i in range(gpiooffs, gpiooffs + gpionum): - gpiopins.append("%s%d*" % (bank, i)) - pins = Pins(prefix, gpiopins, self.bankspec, - suffix, offs, bank, mux, - spec, origsuffix=suffix) - self.pinmerge(pins) - def pinmerge(self, fn): # hack, store the function specs in the pins dict fname = fn.fname @@ -278,7 +174,7 @@ class Pinouts(object): specname = fname + suffix else: specname = fname - #print "fname bank specname suffix ", fname, bank, specname, repr( + # print "fname bank specname suffix ", fname, bank, specname, repr( # suffix) if specname in self.fnspec[fname]: # ok so some declarations may bring in different @@ -298,11 +194,13 @@ class Pinouts(object): for (pinidx, v) in fn.pins.items(): self.update(pinidx, v) + return fname + class Pins(object): def __init__(self, fname, pingroup, bankspec, suffix, offs, bank, mux, - spec=None, limit=None, origsuffix=None): + spec=None, limit=None, origsuffix=None, gangedgrp=None): # function type can be in, out or inout, represented by - + * # strip function type out of each pin name @@ -321,6 +219,7 @@ class Pins(object): self.fname = fname self.pingroup = pingroup + self.gangedgroup = gangedgrp self.bankspec = bankspec self.suffix = suffix self.origsuffix = origsuffix or suffix @@ -357,9 +256,9 @@ class Pins(object): continue if name not in spec: continue - idx_, mux_, bank_ = spec[name] + idx_, mux_ = spec[name] idx_ = names[idx_] - pin = {mux_: (name_, bank_)} + pin = {mux_: (name_, bank)} if idx_ in res: res[idx_].update(pin) else: