Wafer.Driver.Circuits.GPIO.Dispatcher (wafer v1.1.3)

Copy Markdown View Source

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

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

disable(conn, pin_condition)

@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.

enable(conn, pin_condition, metadata \\ nil)

@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.