Merge pull request #810 from antmicro/gpio_interrupts

Add support for interrupts on GPIOIn
This commit is contained in:
enjoy-digital 2021-02-12 15:51:25 +01:00 committed by GitHub
commit 89454d2df3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 45 additions and 1 deletions

View File

@ -10,19 +10,63 @@ from migen.genlib.cdc import MultiReg
from litex.soc.interconnect.csr import *
from litex.soc.interconnect.csr_eventmanager import *
from enum import Enum
# Helpers ------------------------------------------------------------------------------------------
def _to_signal(obj):
return obj.raw_bits() if isinstance(obj, Record) else obj
class IRQ_Type(Enum):
NO_IRQ = 0
RISING_EDGE = 1
FALLING_EDGE = 2
# GPIO Input ---------------------------------------------------------------------------------------
class GPIOIn(Module, AutoCSR):
def __init__(self, pads):
"""GPIO Input
Parameters / Attributes
-----------------------
pads : Object
GPIO Input pads description.
irq : list of IRQ_Type (optional)
List containing IRQ types for each pad. It can take values supported by IRQ_Type Enum.
Example use:
irq = [IRQ_Type.NO_IRQ, IRQ_Type.NO_IRQ, IRQ_Type.FALLING_EDGE, IRQ_Type.RISING_EDGE]
This adds interrupts on pins 2 (falling edge) and 3 (rising edge).
"""
def __init__(self, pads, irq=None):
pads = _to_signal(pads)
self._in = CSRStatus(len(pads), description="GPIO Input(s) Status.")
self.specials += MultiReg(pads, self._in.status)
if irq:
assert(len(irq) <= len(pads))
self.submodules.ev = EventManager()
irq_no = []
for i, irq_type in enumerate(irq):
assert(irq_type, IRQ_Type)
name = "pin" + str(i)
if irq_type == IRQ_Type.RISING_EDGE:
setattr(self.ev, name, EventSourcePulse())
irq_no.append(i)
elif irq_type == IRQ_Type.FALLING_EDGE:
setattr(self.ev, name, EventSourceProcess())
irq_no.append(i)
self.ev.finalize()
sources_u = [v for k, v in xdir(self.ev, True) if isinstance(v, (EventSourcePulse, EventSourceProcess))]
for i, source in enumerate(sources_u):
self.comb += source.trigger.eq(pads[irq_no[i]])
# GPIO Output --------------------------------------------------------------------------------------
class GPIOOut(Module, AutoCSR):