soc/cores/gpio: Simplify GPIOIn IRQ, make polarity configurable and also add optional IRQ to GPIOTristate.
Ex of instance: from litex.soc.cores import gpio gpio_in_pads = Signal(16) self.submodules.gpio_in = gpio.GPIOIn(gpio_in_pads, with_irq=True) self.add_csr("gpio_in")
This commit is contained in:
parent
0d8b6f8fbb
commit
0e7d8219ea
|
@ -17,36 +17,28 @@ from litex.soc.interconnect.csr_eventmanager import *
|
||||||
def _to_signal(obj):
|
def _to_signal(obj):
|
||||||
return obj.raw_bits() if isinstance(obj, Record) else obj
|
return obj.raw_bits() if isinstance(obj, Record) else obj
|
||||||
|
|
||||||
|
|
||||||
|
class _GPIOIRQ(Module, AutoCSR):
|
||||||
|
def __init__(self, in_pads):
|
||||||
|
self._polarity = CSRStorage(len(in_pads), description="GPIO IRQ Polarity: 0: Rising Edge, 1: Falling Edge.")
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
self.submodules.ev = EventManager()
|
||||||
|
for n in range(len(in_pads)):
|
||||||
|
esp = EventSourceProcess(name=f"i{n}", edge="rising")
|
||||||
|
self.comb += esp.trigger.eq(in_pads[n] ^ self._polarity.storage[n])
|
||||||
|
setattr(self.ev, f"i{n}", esp)
|
||||||
|
|
||||||
# GPIO Input ---------------------------------------------------------------------------------------
|
# GPIO Input ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class GPIOIn(Module, AutoCSR):
|
class GPIOIn(Module, AutoCSR):
|
||||||
"""GPIO Input
|
def __init__(self, pads, with_irq=False):
|
||||||
|
|
||||||
Provides a GPIO Input peripheral. An optional IRQ dict can be passed to add rising or falling
|
|
||||||
interrupts to pads.
|
|
||||||
|
|
||||||
Ex: pads=Signal(8), irqs={} : 8-bit Input, No IRQ.
|
|
||||||
pads=Signal(8), irqs={0: "rise", 7: "fall"}: 8-bit Input, rising IRQ on 0, falling IRQ on 1.
|
|
||||||
"""
|
|
||||||
def __init__(self, pads, irqs={}):
|
|
||||||
pads = _to_signal(pads)
|
pads = _to_signal(pads)
|
||||||
|
|
||||||
# Inputs
|
|
||||||
self._in = CSRStatus(len(pads), description="GPIO Input(s) Status.")
|
self._in = CSRStatus(len(pads), description="GPIO Input(s) Status.")
|
||||||
self.specials += MultiReg(pads, self._in.status)
|
self.specials += MultiReg(pads, self._in.status)
|
||||||
|
if with_irq:
|
||||||
# IRQs
|
self.submodules.irq = _GPIOIRQ(self._in.status)
|
||||||
if len(irqs):
|
|
||||||
self.submodules.ev = EventManager()
|
|
||||||
for n, irq_type in irqs.items():
|
|
||||||
assert irq_type in ["fall", "falling", "rise", "rising"]
|
|
||||||
assert len(pads) > n
|
|
||||||
name = f"i{n}"
|
|
||||||
if irq_type in ["rise", "rising"]:
|
|
||||||
setattr(self.ev, f"i{n}", EventSourcePulse())
|
|
||||||
if irq_type in ["fall", "falling"]:
|
|
||||||
setattr(self.ev, f"i{n}", EventSourceProcess())
|
|
||||||
self.comb += getattr(self.ev, f"i{n}").trigger.eq(pads[n])
|
|
||||||
|
|
||||||
# GPIO Output --------------------------------------------------------------------------------------
|
# GPIO Output --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -69,7 +61,7 @@ class GPIOInOut(Module):
|
||||||
# GPIO Tristate ------------------------------------------------------------------------------------
|
# GPIO Tristate ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class GPIOTristate(Module, AutoCSR):
|
class GPIOTristate(Module, AutoCSR):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads, with_irq=False):
|
||||||
assert isinstance(pads, Signal)
|
assert isinstance(pads, Signal)
|
||||||
nbits = len(pads)
|
nbits = len(pads)
|
||||||
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
|
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
|
||||||
|
@ -84,3 +76,6 @@ class GPIOTristate(Module, AutoCSR):
|
||||||
self.comb += t.oe.eq(self._oe.storage[i])
|
self.comb += t.oe.eq(self._oe.storage[i])
|
||||||
self.comb += t.o.eq(self._out.storage[i])
|
self.comb += t.o.eq(self._out.storage[i])
|
||||||
self.specials += MultiReg(t.i, self._in.status[i])
|
self.specials += MultiReg(t.i, self._in.status[i])
|
||||||
|
|
||||||
|
if with_irq:
|
||||||
|
self.submodules.irq = _GPIOIRQ(self._in.status)
|
||||||
|
|
Loading…
Reference in New Issue