This module implements a simple dispatcher for GPIO interrupts when using
Circuits.GPIO.
Because the Circuits' interrupt doesn't provide an indication of whether the pin is rising or falling we store the last known pin state and use it to compare.
Each open ref can only have a single hardware interrupt trigger at a time,
so the dispatcher tracks how many enables are currently outstanding for each
edge on each ref and arms the hardware with the union. Sequential calls of
enable(conn, :rising) and enable(conn, :falling) therefore leave the
ref armed for :both, not just the last-requested edge.
Backends that emit a different gpio_spec form than was passed to open/3
Circuits.GPIO documents that the gpio_spec element of an interrupt
message equals the spec passed to open/3, but some backends (for example
circuits_ft232h's GPIO poller) emit a different normalised form. The
dispatcher learns every spec form a ref may appear under at enable time —
by consulting Circuits.GPIO.identifiers/1 — so interrupts are matched
back to the originating conn regardless of which form the backend chose.
Summary
Functions
Returns a specification to start this module under a supervisor.
Disable interrupts for this connection using the specified pin_condition.
Enable interrupts for this connection using the specified pin_condition.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec disable(Wafer.Conn.t(), Wafer.GPIO.pin_condition()) :: {:ok, Wafer.Conn.t()} | {:error, reason :: any()}
Disable interrupts for this connection using the specified pin_condition.
@spec enable(Wafer.Conn.t(), Wafer.GPIO.pin_condition(), any()) :: {:ok, Wafer.Conn.t()} | {:error, reason :: any()}
Enable interrupts for this connection using the specified pin_condition.
The caller is registered as a subscriber before the hardware interrupt is armed, so any edge that fires after arming is guaranteed to find a subscriber in the registry.