gpio: add support for interrupts on GPIOIn
This commit is contained in:
parent
4c1dbf9991
commit
15b3d932a4
|
@ -10,19 +10,63 @@ from migen.genlib.cdc import MultiReg
|
||||||
|
|
||||||
from litex.soc.interconnect.csr import *
|
from litex.soc.interconnect.csr import *
|
||||||
|
|
||||||
|
from litex.soc.interconnect.csr_eventmanager import *
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
# Helpers ------------------------------------------------------------------------------------------
|
# Helpers ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
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 IRQ_Type(Enum):
|
||||||
|
NO_IRQ = 0
|
||||||
|
RISING_EDGE = 1
|
||||||
|
FALLING_EDGE = 2
|
||||||
|
|
||||||
# GPIO Input ---------------------------------------------------------------------------------------
|
# GPIO Input ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class GPIOIn(Module, AutoCSR):
|
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)
|
pads = _to_signal(pads)
|
||||||
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 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 --------------------------------------------------------------------------------------
|
# GPIO Output --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class GPIOOut(Module, AutoCSR):
|
class GPIOOut(Module, AutoCSR):
|
||||||
|
|
Loading…
Reference in New Issue