Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions lib/gpio.ex
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,15 @@ defmodule Circuits.GPIO do
end

@doc """
Return dynamic configuration and status information about a GPIO
Return dynamic configuration and status information about a GPIO or handle

See `t:gpio_spec/0` for the ways of referring to GPIOs. If the GPIO is found,
this function returns information about the GPIO.
Pass a `t:gpio_spec/0` to query a GPIO without opening it, or a `t:Handle.t/0`
to query an open GPIO. If the GPIO is found, this function returns information
about the GPIO. Status for GPIO groups is not supported.
"""
@spec status(gpio_spec()) :: {:ok, status()} | {:error, atom()}
@spec status(gpio_spec() | Handle.t()) :: {:ok, status()} | {:error, atom()}
def status(handle) when is_struct(handle), do: Handle.status(handle)

Comment on lines +246 to +248
def status(gpio_spec) do
{backend, backend_defaults} = default_backend()

Expand Down
14 changes: 12 additions & 2 deletions lib/gpio/cdev.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule Circuits.GPIO.CDev do
alias Circuits.GPIO.Handle
alias Circuits.GPIO.Nif

defstruct [:ref]
defstruct [:ref, :locations]

@impl Backend
def enumerate(options) do
Expand Down Expand Up @@ -128,7 +128,8 @@ defmodule Circuits.GPIO.CDev do
with {:ok, controller, offsets} <- resolve_group(specs, options),
{:ok, ref} <-
Nif.open(gpio_spec, {controller, offsets}, direction, value, pull_mode, drive_mode) do
{:ok, %__MODULE__{ref: ref}}
locations = Enum.map(offsets, &{controller, &1})
{:ok, %__MODULE__{ref: ref, locations: locations}}
end
end

Expand Down Expand Up @@ -173,6 +174,15 @@ defmodule Circuits.GPIO.CDev do
Nif.read(ref)
end

@impl Handle
def status(%Circuits.GPIO.CDev{locations: [location]}) do
Nif.status(location)
end

def status(%Circuits.GPIO.CDev{}) do
{:error, :group_handle}
end

@impl Handle
def write(%Circuits.GPIO.CDev{ref: ref}, value) do
Nif.write(ref, value)
Expand Down
5 changes: 5 additions & 0 deletions lib/gpio/handle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ defprotocol Circuits.GPIO.Handle do
@spec read(t()) :: GPIO.value()
def read(handle)

# Return dynamic GPIO configuration and status information.
@doc false
@spec status(t()) :: {:ok, GPIO.status()} | {:error, atom()}
def status(handle)

# Set the GPIO state. For a group, this is an integer with one bit per line.
@doc false
@spec write(t(), GPIO.value()) :: :ok
Expand Down
25 changes: 24 additions & 1 deletion test/circuits_gpio_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ defmodule Circuits.GPIOTest do
end
end

describe "status/2" do
describe "status/1" do
test "all gpio_spec examples" do
expected = %{consumer: "", direction: :input, pull_mode: :none, drive_mode: :push_pull}

Expand Down Expand Up @@ -215,6 +215,29 @@ defmodule Circuits.GPIOTest do

GPIO.close(gpio)
end

test "status reports an open GPIO handle" do
{:ok, gpio} = GPIO.open({@gpiochip, 1}, :input, pull_mode: :pullup)

assert GPIO.status(gpio) ==
{:ok,
%{
consumer: "stub",
direction: :input,
pull_mode: :pullup,
drive_mode: :push_pull
}}

GPIO.close(gpio)
end

test "status does not support GPIO groups" do
{:ok, gpio} = GPIO.open([{@gpiochip, 0}, {@gpiochip, 1}], :input)

assert GPIO.status(gpio) == {:error, :group_handle}

GPIO.close(gpio)
end
end

describe "drive_mode" do
Expand Down