From 6123ac8493d332cfabb8619a89186e96d2faab58 Mon Sep 17 00:00:00 2001 From: James Harton Date: Wed, 24 Apr 2024 14:20:57 +1200 Subject: [PATCH] feat!: Remove ElixirALE support. (#67) Reviewed-on: https://harton.dev/james/wafer/pulls/67 Co-authored-by: James Harton Co-committed-by: James Harton --- README.md | 10 +- lib/wafer.ex | 3 - lib/wafer/application.ex | 1 - lib/wafer/chip.ex | 8 +- lib/wafer/drivers/circuits/gpio/wrapper.ex | 4 +- lib/wafer/drivers/elixir_ale/gpio.ex | 84 ------- .../drivers/elixir_ale/gpio/dispatcher.ex | 65 ------ lib/wafer/drivers/elixir_ale/gpio/wrapper.ex | 27 --- lib/wafer/drivers/elixir_ale/i2c.ex | 124 ----------- lib/wafer/drivers/elixir_ale/i2c/wrapper.ex | 39 ---- lib/wafer/drivers/elixir_ale/spi.ex | 70 ------ lib/wafer/drivers/elixir_ale/spi/wrapper.ex | 21 -- lib/wafer/gpio.ex | 5 +- lib/wafer/i2c.ex | 4 +- lib/wafer/interrupt_registry.ex | 6 +- lib/wafer/registers.ex | 2 +- lib/wafer/spi.ex | 8 +- mix.exs | 1 - mix.lock | 1 - .../acceptance/elixir_ale_i2c_device_test.exs | 46 ---- .../elixir_ale_gpio_dispatcher_test.exs | 136 ------------ test/drivers/elixir_ale_gpio_test.exs | 116 ---------- test/drivers/elixir_ale_i2c_test.exs | 207 ------------------ test/drivers/elixir_ale_spi_test.exs | 57 ----- test/test_helper.exs | 4 - 25 files changed, 23 insertions(+), 1026 deletions(-) delete mode 100644 lib/wafer/drivers/elixir_ale/gpio.ex delete mode 100644 lib/wafer/drivers/elixir_ale/gpio/dispatcher.ex delete mode 100644 lib/wafer/drivers/elixir_ale/gpio/wrapper.ex delete mode 100644 lib/wafer/drivers/elixir_ale/i2c.ex delete mode 100644 lib/wafer/drivers/elixir_ale/i2c/wrapper.ex delete mode 100644 lib/wafer/drivers/elixir_ale/spi.ex delete mode 100644 lib/wafer/drivers/elixir_ale/spi/wrapper.ex delete mode 100644 test/acceptance/elixir_ale_i2c_device_test.exs delete mode 100644 test/drivers/elixir_ale_gpio_dispatcher_test.exs delete mode 100644 test/drivers/elixir_ale_gpio_test.exs delete mode 100644 test/drivers/elixir_ale_i2c_test.exs delete mode 100644 test/drivers/elixir_ale_spi_test.exs diff --git a/README.md b/README.md index 4d45fc1..8f55de1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Wafer is an OTP application that assists with writing drivers for peripherals us Wafer provides Elixir protocols for interacting with device registers and dealing with GPIO, so that you can use directly connected hardware GPIO pins or GPIO expanders such as the [MCP23008](https://www.microchip.com/wwwproducts/en/MCP23008) or the [CD74HC595](http://www.ti.com/product/CD74HC595) SPI shift register. -Wafer implements the [GPIO](https://hexdocs.pm/wafer/Wafer.GPIOProto.html) and [Chip](https://hexdocs.pm/wafer/Wafer.Chip.html) protocols for [ElixirALE](https://hex.pm/packages/elixir_ale)'s GPIO and I2C drivers, [Circuits.GPIO](https://hex.pm/packages/circuits_gpio) and [Circuits.I2C](https://hex.pm/packages/circuits_i2c). Implementing it for SPI should also be trivial, I just don't have any SPI devices to test with at the moment. +Wafer implements the [GPIO](https://hexdocs.pm/wafer/Wafer.GPIOProto.html) and [Chip](https://hexdocs.pm/wafer/Wafer.Chip.html) protocols for [Circuits.GPIO](https://hex.pm/packages/circuits_gpio) and [Circuits.I2C](https://hex.pm/packages/circuits_i2c). Implementing it for SPI should also be trivial, I just don't have any SPI devices to test with at the moment. Documentation for the main branch can always be found [here](https://docs.harton.nz/james/wafer/). @@ -112,10 +112,10 @@ end ## Running the tests -I've included stub implementations of the parts of `ElixirALE` and `Circuits` -that are interacted with by this project, so the tests should run and pass on -machines without physical hardware interfaces. If you have a Raspberry Pi with -a Pi Sense Hat connected you can run the tests with the `SENSE_HAT_PRESENT=true` +I've included stub implementations of the parts of `Circuits` that are +interacted with by this project, so the tests should run and pass on machines +without physical hardware interfaces. If you have a Raspberry Pi with a Pi Sense +Hat connected you can run the tests with the `SENSE_HAT_PRESENT=true` environment variable set and it will perform integration tests with two of the sensors on this device. diff --git a/lib/wafer.ex b/lib/wafer.ex index b7e80c0..802f05f 100644 --- a/lib/wafer.ex +++ b/lib/wafer.ex @@ -5,8 +5,5 @@ defmodule Wafer do This library doesn't do much on it's own, it is used to help with some of the repetitive tasks of writing drivers for hardware peripherals such as I2C and SPI connected sensors. - - Wafer works with both ElixirALE and Circuits. As such it's up to you to - define which dependency you're using. """ end diff --git a/lib/wafer/application.ex b/lib/wafer/application.ex index be0b075..c00edc5 100644 --- a/lib/wafer/application.ex +++ b/lib/wafer/application.ex @@ -9,7 +9,6 @@ defmodule Wafer.Application do def start(_type, _args) do children = [ {Registry, [keys: :duplicate, name: Wafer.InterruptRegistry]}, - Wafer.Driver.ElixirALE.GPIO.Dispatcher, Wafer.Driver.Circuits.GPIO.Dispatcher ] diff --git a/lib/wafer/chip.ex b/lib/wafer/chip.ex index af77596..33f2d13 100644 --- a/lib/wafer/chip.ex +++ b/lib/wafer/chip.ex @@ -52,7 +52,7 @@ defprotocol Wafer.Chip do ## Example - iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c-1", address: 0x68) + iex> {:ok, conn} = Circuits.I2C.acquire(bus: "i2c-1", address: 0x68) ...> Chip.read_register(conn, 0, 1) {:ok, <<0>>} """ @@ -71,7 +71,7 @@ defprotocol Wafer.Chip do ## Example - iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c", address: 0x68) + iex> {:ok, conn} = Circuits.I2C.acquire(bus: "i2c", address: 0x68) ...> Chip.write_register(conn, 0, <<0>>) {:ok, conn} """ @@ -88,7 +88,7 @@ defprotocol Wafer.Chip do - `conn` a type which implements the `Wafer.Conn` behaviour. - `register_address` the address of the register to swap. - - `new_data` the data to write to the regsiter. + - `new_data` the data to write to the register. ## Returns @@ -96,7 +96,7 @@ defprotocol Wafer.Chip do ## Example - iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c", address: 0x68) + iex> {:ok, conn} = Circuits.I2C.acquire(bus: "i2c", address: 0x68) ...> Chip.swap_register(conn, 0, <<1>>) {:ok, <<0>>, conn} """ diff --git a/lib/wafer/drivers/circuits/gpio/wrapper.ex b/lib/wafer/drivers/circuits/gpio/wrapper.ex index 1a53f64..e171322 100644 --- a/lib/wafer/drivers/circuits/gpio/wrapper.ex +++ b/lib/wafer/drivers/circuits/gpio/wrapper.ex @@ -5,13 +5,13 @@ defmodule Wafer.Driver.Circuits.GPIO.Wrapper do defdelegate close(gpio), to: Circuits.GPIO @compile {:no_warn_undefined, Circuits.GPIO} - defdelegate info(), to: Circuits.GPIO + defdelegate backend_info(gpio \\ nil), to: Circuits.GPIO @compile {:no_warn_undefined, Circuits.GPIO} defdelegate open(pin_number, pin_direction, options \\ []), to: Circuits.GPIO @compile {:no_warn_undefined, Circuits.GPIO} - defdelegate pin(gpio), to: Circuits.GPIO + defdelegate identifiers(gpio), to: Circuits.GPIO @compile {:no_warn_undefined, Circuits.GPIO} defdelegate read(gpio), to: Circuits.GPIO diff --git a/lib/wafer/drivers/elixir_ale/gpio.ex b/lib/wafer/drivers/elixir_ale/gpio.ex deleted file mode 100644 index 90de620..0000000 --- a/lib/wafer/drivers/elixir_ale/gpio.ex +++ /dev/null @@ -1,84 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.GPIO do - defstruct ~w[direction pid pin]a - @behaviour Wafer.Conn - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.GPIO - import Wafer.Guards - - @moduledoc """ - A connection to a native GPIO pin via ElixirALE's GPIO driver. - - Implements the `Wafer.Conn` behaviour as well as the `Wafer.GPIO` protocol. - """ - - @type t :: %__MODULE__{pid: pid} - - @type options :: [option] - @type option :: {:pin, non_neg_integer} | {:direction, GPIO.pin_direction()} | {:force, boolean} - - @doc """ - Acquire a connection to the specified GPIO pin using the ElixirALE GPIO driver. - - ## Options - - - `:pin` (required) - the integer pin number. Hardware dependent. - - `:direction` - either `:in` or `:out`. Defaults to `:out`. - """ - @spec acquire(options) :: {:ok, t} | {:error, reason :: any} - def acquire(opts) when is_list(opts) do - with {:ok, pin} when is_pin_number(pin) <- Keyword.fetch(opts, :pin), - direction when direction in [:in, :out] <- Keyword.get(opts, :direction, :out), - direction <- String.to_atom("#{direction}put"), - {:ok, pid} <- Wrapper.start_link(pin, direction, Keyword.drop(opts, ~w[pin direction]a)) do - {:ok, %__MODULE__{pid: pid, pin: pin, direction: direction}} - else - :error -> {:error, "ElixirALE.GPIO requires a `pin` option."} - {:error, reason} -> {:error, reason} - end - end -end - -defimpl Wafer.Release, for: Wafer.Driver.ElixirALE.GPIO do - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.Driver.ElixirALE.GPIO - - @doc """ - Release all resources related to this GPIO pin connection. - - Note that other connections may still be using the pin. - """ - @spec release(GPIO.t()) :: :ok | {:error, reason :: any} - def release(%GPIO{pid: pid} = _conn), do: Wrapper.release(pid) -end - -defimpl Wafer.GPIO, for: Wafer.Driver.ElixirALE.GPIO do - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.Driver.ElixirALE.GPIO.Dispatcher - import Wafer.Guards - - def read(%{pid: pid} = _conn) do - case Wrapper.read(pid) do - value when is_pin_value(value) -> {:ok, value} - {:error, reason} -> {:error, reason} - other -> {:error, "Invalid response from driver: #{inspect(other)}"} - end - end - - def write(%{pid: pid} = conn, value) when is_pid(pid) and is_pin_value(value) do - with :ok <- Wrapper.write(pid, value), do: {:ok, conn} - end - - def direction(_conn, _direction), do: {:error, :not_supported} - - def enable_interrupt(conn, pin_condition, metadata \\ nil), - do: Dispatcher.enable(conn, pin_condition, metadata) - - def disable_interrupt(conn, pin_condition), - do: Dispatcher.disable(conn, pin_condition) - - def pull_mode(_conn, _pull_mode), do: {:error, :not_supported} -end - -defimpl Wafer.DeviceID, for: Wafer.Driver.ElixirALE.GPIO do - def id(%{pin: pin}), do: {Wafer.Driver.ElixirALE.GPIO, pin} -end diff --git a/lib/wafer/drivers/elixir_ale/gpio/dispatcher.ex b/lib/wafer/drivers/elixir_ale/gpio/dispatcher.ex deleted file mode 100644 index d1eec03..0000000 --- a/lib/wafer/drivers/elixir_ale/gpio/dispatcher.ex +++ /dev/null @@ -1,65 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.GPIO.Dispatcher do - use GenServer - alias __MODULE__ - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.{Conn, GPIO, InterruptRegistry} - - @allowed_pin_conditions ~w[rising falling both]a - - @moduledoc """ - This module implements a simple dispatcher for GPIO interrupts when using - `ElixirALE`. - """ - - @doc false - def start_link(opts), - do: GenServer.start_link(__MODULE__, [opts], name: Dispatcher) - - @doc """ - Enable interrupts for this connection using the specified pin_condition. - """ - @spec enable(Conn.t(), GPIO.pin_condition(), any) :: {:ok, Conn.t()} | {:error, reason :: any} - def enable(%{pin: pin} = conn, pin_condition, metadata \\ nil) - when pin_condition in @allowed_pin_conditions do - with {:ok, conn} <- GenServer.call(Dispatcher, {:enable, conn, pin_condition}), - :ok <- InterruptRegistry.subscribe(key(pin), pin_condition, conn, metadata) do - {:ok, conn} - end - end - - @doc """ - Disable interrupts for this connection on the specified pin_condition. - """ - @spec disable(Conn.t(), GPIO.pin_condition()) :: {:ok, Conn.t()} | {:error, reason :: any} - def disable(conn, pin_condition) when pin_condition in @allowed_pin_conditions, - do: GenServer.call(Dispatcher, {:disable, conn, pin_condition}) - - @impl true - def init(_opts) do - {:ok, %{}} - end - - @impl true - def handle_call({:enable, %{pid: pid} = conn, pin_condition}, _from, state) - when pin_condition in @allowed_pin_conditions do - case Wrapper.set_int(pid, pin_condition) do - :ok -> {:reply, {:ok, conn}, state} - {:error, reason} -> {:reply, {:error, reason}, state} - end - end - - def handle_call({:disable, %{pin: pin} = conn, pin_condition}, _from, state) - when pin_condition in @allowed_pin_conditions do - :ok = InterruptRegistry.unsubscribe(key(pin), pin_condition, conn) - {:reply, {:ok, conn}, state} - end - - @impl true - def handle_info({:gpio_interrupt, pin, condition}, state) - when condition in @allowed_pin_conditions do - {:ok, _} = InterruptRegistry.publish(key(pin), condition) - {:noreply, state} - end - - defp key(pin), do: {__MODULE__, pin} -end diff --git a/lib/wafer/drivers/elixir_ale/gpio/wrapper.ex b/lib/wafer/drivers/elixir_ale/gpio/wrapper.ex deleted file mode 100644 index a92e2c3..0000000 --- a/lib/wafer/drivers/elixir_ale/gpio/wrapper.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.GPIO.Wrapper do - @moduledoc false - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate child_spec(arg), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate init(list), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate pin(pid), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate read(pid), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate release(pid), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate set_int(pid, direction), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate start_link(pin, pin_direction, opts \\ []), to: ElixirALE.GPIO - - @compile {:no_warn_undefined, ElixirALE.GPIO} - defdelegate write(pid, value), to: ElixirALE.GPIO -end diff --git a/lib/wafer/drivers/elixir_ale/i2c.ex b/lib/wafer/drivers/elixir_ale/i2c.ex deleted file mode 100644 index 8edc1c8..0000000 --- a/lib/wafer/drivers/elixir_ale/i2c.ex +++ /dev/null @@ -1,124 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.I2C do - defstruct ~w[address bus pid]a - alias Wafer.Driver.ElixirALE.I2C.Wrapper - alias Wafer.I2C - import Wafer.Guards - - @moduledoc """ - A connection to a chip via ElixirALE's I2C driver. - - Implements the `Wafer.Conn` behaviour as well as the `Wafer.Chip` and `Wafer.I2C` protocols. - """ - - @type t :: %__MODULE__{address: I2C.address(), bus: binary, pid: pid} - - @type options :: [option] - @type option :: {:bus_name, binary} | {:address, I2C.address()} - - @doc """ - Acquire a connection to a peripheral using the ElixirALE I2C driver on the - specified bus and address. - """ - @spec acquire(options) :: {:ok, t} | {:error, reason :: any} - def acquire(opts) when is_list(opts) do - with {:ok, bus} when is_binary(bus) <- Keyword.fetch(opts, :bus_name), - {:ok, address} when is_i2c_address(address) <- Keyword.fetch(opts, :address), - {:ok, pid} <- Wrapper.start_link(bus, address), - devices when is_list(devices) <- Wrapper.detect_devices(pid), - true <- Keyword.get(opts, :force, false) || Enum.member?(devices, address) do - {:ok, %__MODULE__{bus: bus, address: address, pid: pid}} - else - false -> - {:error, "No device detected at address. Pass `force: true` to override."} - - :error -> - {:error, "ElixirALE.I2C requires both `bus_name` and `address` options."} - - {:error, reason} -> - {:error, reason} - end - end -end - -defimpl Wafer.Release, for: Wafer.Driver.ElixirALE.I2C do - alias Wafer.Driver.ElixirALE.I2C.Wrapper - alias Wafer.Driver.ElixirALE.I2C - - @doc """ - Release all resources associated with this I2C device. - """ - @spec release(I2C.t()) :: :ok | {:error, reason :: any} - def release(%I2C{pid: pid} = _conn) when is_pid(pid), do: Wrapper.release(pid) -end - -defimpl Wafer.Chip, for: Wafer.Driver.ElixirALE.I2C do - alias Wafer.Driver.ElixirALE.I2C.Wrapper - import Wafer.Guards - - def read_register(%{pid: pid}, register_address, bytes) - when is_pid(pid) and is_register_address(register_address) and is_byte_size(bytes) do - case Wrapper.write_read(pid, <>, bytes) do - data when is_binary(data) and byte_size(data) == bytes -> {:ok, data} - {:error, reason} -> {:error, reason} - other -> {:error, "Invalid response from driver: #{inspect(other)}"} - end - end - - def read_register(_conn, _register_address, _bytes), do: {:error, "Invalid argument"} - - def write_register(%{pid: pid} = conn, register_address, data) - when is_pid(pid) and is_register_address(register_address) and is_binary(data) do - with :ok <- Wrapper.write(pid, <>), do: {:ok, conn} - end - - def write_register(_conn, _register_address, _data), do: {:error, "Invalid argument"} - - def swap_register(conn, register_address, data) - when is_register_address(register_address) and is_binary(data) do - with {:ok, old_data} <- read_register(conn, register_address, byte_size(data)), - {:ok, conn} <- write_register(conn, register_address, data) do - {:ok, old_data, conn} - end - end - - def swap_register(_conn, _register_address, _data), do: {:error, "Invalid argument"} -end - -defimpl Wafer.I2C, for: Wafer.Driver.ElixirALE.I2C do - import Wafer.Guards - alias Wafer.Driver.ElixirALE.I2C.Wrapper - - def read(%{pid: pid}, bytes, options \\ []) - when is_pid(pid) and is_byte_size(bytes) and is_list(options) do - case Wrapper.read(pid, bytes) do - data when is_binary(data) and byte_size(data) == bytes -> {:ok, data} - {:error, reason} -> {:error, reason} - other -> {:error, "Invalid response from driver: #{inspect(other)}"} - end - end - - def write(%{pid: pid} = conn, data, options \\ []) - when is_pid(pid) and is_binary(data) and is_list(options) do - with :ok <- Wrapper.write(pid, data), do: {:ok, conn} - end - - def write_read(%{pid: pid} = conn, data, bytes, options \\ []) - when is_pid(pid) and is_binary(data) and is_byte_size(bytes) and is_list(options) do - case Wrapper.write_read(pid, data, bytes) do - data when is_binary(data) and byte_size(data) == bytes -> {:ok, data, conn} - {:error, reason} -> {:error, reason} - other -> {:error, "Invalid response from driver: #{inspect(other)}"} - end - end - - def detect_devices(%{pid: pid}) do - case Wrapper.detect_devices(pid) do - devices when is_list(devices) -> {:ok, devices} - {:error, reason} -> {:error, reason} - end - end -end - -defimpl Wafer.DeviceID, for: Wafer.Driver.ElixirALE.I2C do - def id(%{address: address, bus: bus}), do: {Wafer.Driver.ElixirALE.I2C, bus, address} -end diff --git a/lib/wafer/drivers/elixir_ale/i2c/wrapper.ex b/lib/wafer/drivers/elixir_ale/i2c/wrapper.ex deleted file mode 100644 index 8cd0efb..0000000 --- a/lib/wafer/drivers/elixir_ale/i2c/wrapper.ex +++ /dev/null @@ -1,39 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.I2C.Wrapper do - @moduledoc false - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate child_spec(arg), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate detect_devices(pid_or_devname), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate device_names(), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate init(list), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate read(pid, count), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate read_device(pid, address, count), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate release(pid), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate start_link(devname, address, opts \\ []), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate write(pid, data), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate write_device(pid, address, data), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate write_read(pid, write_data, read_count), to: ElixirALE.I2C - - @compile {:no_warn_undefined, ElixirALE.I2C} - defdelegate write_read_device(pid, address, write_data, read_count), to: ElixirALE.I2C -end diff --git a/lib/wafer/drivers/elixir_ale/spi.ex b/lib/wafer/drivers/elixir_ale/spi.ex deleted file mode 100644 index d00c918..0000000 --- a/lib/wafer/drivers/elixir_ale/spi.ex +++ /dev/null @@ -1,70 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.SPI do - defstruct ~w[bus pid]a - @behaviour Wafer.Conn - alias Wafer.Driver.ElixirALE.SPI.Wrapper - - @moduledoc """ - A connection to a chip via ElixirALE's SPI driver. - - Implements the `Wafer.Conn` behaviour as well as the `Wafer.SPI` protocol. - """ - - @type t :: %__MODULE__{bus: binary, pid: pid} - - @type options :: [option | driver_option] - @type option :: {:bus_name, binary} - # These options are passed unchanged to the underlying driver. - @type driver_option :: - {:mode, 0..3} - | {:bits_per_word, 0..16} - | {:speed_hz, pos_integer} - | {:delay_us, non_neg_integer} - - @doc """ - Acquire a connection to a peripheral using the ElixirALE' SPI driver on the - specified bus and address. - """ - @spec acquire(options) :: {:ok, t} | {:error, reason :: any} - def acquire(opts) when is_list(opts) do - with {:ok, bus} when is_binary(bus) <- Keyword.fetch(opts, :bus_name), - {:ok, pid} when is_pid(pid) <- - Wrapper.start_link(bus, Keyword.delete(opts, :bus_name), []) do - {:ok, %__MODULE__{bus: bus, pid: pid}} - else - :error -> {:error, "ElixirALE.SPI requires a `bus_name` option"} - {:error, reason} -> {:error, reason} - end - end -end - -defimpl Wafer.Release, for: Wafer.Driver.ElixirALE.SPI do - alias Wafer.Driver.ElixirALE.SPI.Wrapper - alias Wafer.Driver.ElixirALE.SPI - - @doc """ - Close the SPI bus connection. - """ - @spec release(SPI.t()) :: :ok | {:error, reason :: any} - def release(%SPI{pid: pid} = _conn) when is_pid(pid), do: Wrapper.release(pid) -end - -defimpl Wafer.SPI, for: Wafer.Driver.ElixirALE.SPI do - alias Wafer.Driver.ElixirALE.SPI.Wrapper - - def transfer(%{pid: pid} = conn, data) when is_pid(pid) and is_binary(data) do - case Wrapper.transfer(pid, data) do - read_data when is_binary(read_data) and byte_size(read_data) == byte_size(data) -> - {:ok, read_data, conn} - - {:error, reason} -> - {:error, reason} - - other -> - {:error, "Invalid response from driver: #{inspect(other)}"} - end - end -end - -defimpl Wafer.DeviceID, for: Wafer.Driver.ElixirALE.SPI do - def id(%{bus: bus}), do: {Wafer.Driver.ElixirALE.SPI, bus} -end diff --git a/lib/wafer/drivers/elixir_ale/spi/wrapper.ex b/lib/wafer/drivers/elixir_ale/spi/wrapper.ex deleted file mode 100644 index 4a1792b..0000000 --- a/lib/wafer/drivers/elixir_ale/spi/wrapper.ex +++ /dev/null @@ -1,21 +0,0 @@ -defmodule Wafer.Driver.ElixirALE.SPI.Wrapper do - @moduledoc false - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate child_spec(arg), to: ElixirALE.SPI - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate device_names(), to: ElixirALE.SPI - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate init(arg), to: ElixirALE.SPI - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate release(pid), to: ElixirALE.SPI - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate start_link(devname, spi_opts \\ [], opts \\ []), to: ElixirALE.SPI - - @compile {:no_warn_undefined, ElixirALE.SPI} - defdelegate transfer(pid, data), to: ElixirALE.SPI -end diff --git a/lib/wafer/gpio.ex b/lib/wafer/gpio.ex index 3005747..fb1ffe7 100644 --- a/lib/wafer/gpio.ex +++ b/lib/wafer/gpio.ex @@ -68,13 +68,12 @@ defprotocol Wafer.GPIO do Interrupts will be sent to the calling process as messages in the form of `{:interrupt, Conn.t(), pin_condition, metadata | nil}`. - ## Implementors note + ## Implementers note `Wafer` starts it's own `Registry` named `Wafer.InterruptRegistry` which you can use to publish your interrupts to using the above format. The registry key is set as follows: `{PublishingModule, pin, pin_condition}`. You can see - examples in the `Circuits.GPIO.Dispatcher` and `ElixirALE.GPIO.Dispatcher` - modules. + examples in the `Circuits.GPIO.Dispatcher` module. """ @spec enable_interrupt(Conn.t(), pin_condition, any) :: {:ok, Conn.t()} | {:error, reason :: any} diff --git a/lib/wafer/i2c.ex b/lib/wafer/i2c.ex index 4961ecd..31c84cc 100644 --- a/lib/wafer/i2c.ex +++ b/lib/wafer/i2c.ex @@ -6,8 +6,8 @@ defprotocol Wafer.I2C do want to use the `Chip` protocol for working with registers, but this is provided for consistency's sake. - This API is extremely similar to the `ElixirALE.I2C` and `Circuits.I2C` APIs, - except that it takes a `Conn` which implements `I2C` as an argument. + This API is extremely similar to the `Circuits.I2C` APIs, except that it takes + a `Conn` which implements `I2C` as an argument. ## Deriving diff --git a/lib/wafer/interrupt_registry.ex b/lib/wafer/interrupt_registry.ex index 2e03223..b63c3cc 100644 --- a/lib/wafer/interrupt_registry.ex +++ b/lib/wafer/interrupt_registry.ex @@ -7,9 +7,9 @@ defmodule Wafer.InterruptRegistry do This module provides Wafer's interrupt registry. This allows multiple subscribers to be subscribed to interrupts from many different pins. - It is used by `Driver.Circuits.GPIO.Dispatcher` and - `Driver.ElixirALE.GPIO.Dispatcher` and you should probably use it if you're - writing your own driver which supports sending interrupts to subscribers. + It is used by `Driver.Circuits.GPIO.Dispatcher` and you should probably use it + if you're writing your own driver which supports sending interrupts to + subscribers. """ @type key :: any diff --git a/lib/wafer/registers.ex b/lib/wafer/registers.ex index 570c095..7c75454 100644 --- a/lib/wafer/registers.ex +++ b/lib/wafer/registers.ex @@ -88,7 +88,7 @@ defmodule Wafer.Registers do when is_function(callback, 1) do with {:ok, data} <- Chip.read_register(conn, 0x01, 1), new_data when is_binary(new_data) and byte_size(new_data) == 1 <- callback.(data), - {:ok, conn} <- Chip.write_regsiter(conn, 0x01, new_data), + {:ok, conn} <- Chip.write_register(conn, 0x01, new_data), do: {:ok, conn} end diff --git a/lib/wafer/spi.ex b/lib/wafer/spi.ex index c595cde..fae35bc 100644 --- a/lib/wafer/spi.ex +++ b/lib/wafer/spi.ex @@ -4,10 +4,10 @@ defprotocol Wafer.SPI do @moduledoc """ A (very simple) protocol for interacting with SPI connected devices. - This API is a minimal version of the `ElixirALE.SPI` and `Circuits.SPI` APIs, - except that it takes a `Conn` which implements `SPI` as an argument. If you - want to use any advanced features, such as bus detection, I advise you to - interact with the underlying driver directly. + This API is a minimal version of the `Circuits.SPI` APIs, except that it takes + a `Conn` which implements `SPI` as an argument. If you want to use any + advanced features, such as bus detection, I advise you to interact with the + underlying driver directly. ## Deriving diff --git a/mix.exs b/mix.exs index 5b1e1a8..f990295 100644 --- a/mix.exs +++ b/mix.exs @@ -62,7 +62,6 @@ defmodule Wafer.MixProject do {:circuits_i2c, "< 3.0.0", optional: true} end, {:circuits_spi, "< 3.0.0", optional: true}, - {:elixir_ale, "~> 1.2", optional: true}, # Dev/test {:credo, "~> 1.6", devtest}, diff --git a/mix.lock b/mix.lock index 7a8cbb1..e684e63 100644 --- a/mix.lock +++ b/mix.lock @@ -9,7 +9,6 @@ "doctor": {:hex, :doctor, "0.21.0", "20ef89355c67778e206225fe74913e96141c4d001cb04efdeba1a2a9704f1ab5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a227831daa79784eb24cdeedfa403c46a4cb7d0eab0e31232ec654314447e4e0"}, "earmark": {:hex, :earmark, "1.4.46", "8c7287bd3137e99d26ae4643e5b7ef2129a260e3dcf41f251750cb4563c8fb81", [:mix], [], "hexpm", "798d86db3d79964e759ddc0c077d5eb254968ed426399fbf5a62de2b5ff8910a"}, "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, - "elixir_ale": {:hex, :elixir_ale, "1.2.1", "07ac2f17a0191b8bd3b0df6b526c7f699a3a4d690c9def573fcb5824eef24d98", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "bfb099137500a3b8c4a1750cf07f2d704897ef9feac3412064bf9edc7d74193c"}, "elixir_make": {:hex, :elixir_make, "0.8.3", "d38d7ee1578d722d89b4d452a3e36bcfdc644c618f0d063b874661876e708683", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "5c99a18571a756d4af7a4d89ca75c28ac899e6103af6f223982f09ce44942cc9"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"}, diff --git a/test/acceptance/elixir_ale_i2c_device_test.exs b/test/acceptance/elixir_ale_i2c_device_test.exs deleted file mode 100644 index ff10a3d..0000000 --- a/test/acceptance/elixir_ale_i2c_device_test.exs +++ /dev/null @@ -1,46 +0,0 @@ -defmodule WaferAcceptanceElixirALE.I2CDeviceTest do - use ExUnit.Case, async: true - - # Only run acceptance tests if the fake drivers are not loaded. - if System.get_env("SENSE_HAT_PRESENT") == "true" do - alias Wafer.Driver.ElixirALE.I2C, as: Driver - - defmodule LPS25H do - use Wafer.Registers - - @moduledoc """ - A not very useful driver for the LPS25H pressure senser on the Pi Sense Hat. - """ - - defregister(:who_am_i, 0x0F, :ro, 1) - defregister(:ctrl_reg1, 0x20, :rw, 1) - - def on?(conn) do - case read_ctrl_reg1(conn) do - {:ok, <<1::integer-size(1), _::integer-size(7)>>} -> true - _ -> false - end - end - - def turn_on(conn), do: write_ctrl_reg1(conn, <<1::integer-size(1), 0::integer-size(7)>>) - def turn_off(conn), do: write_ctrl_reg1(conn, <<0>>) - end - - describe "generated registers" do - test "reading" do - {:ok, conn} = Driver.acquire(bus_name: "i2c-1", address: 0x5C) - - assert {:ok, <<0xBD>>} = LPS25H.read_who_am_i(conn) - end - - test "reading and writing" do - {:ok, conn} = Driver.acquire(bus_name: "i2c-1", address: 0x5C) - - assert {:ok, conn} = LPS25H.turn_on(conn) - assert LPS25H.on?(conn) == true - assert {:ok, conn} = LPS25H.turn_off(conn) - assert LPS25H.on?(conn) == false - end - end - end -end diff --git a/test/drivers/elixir_ale_gpio_dispatcher_test.exs b/test/drivers/elixir_ale_gpio_dispatcher_test.exs deleted file mode 100644 index 3e89e1e..0000000 --- a/test/drivers/elixir_ale_gpio_dispatcher_test.exs +++ /dev/null @@ -1,136 +0,0 @@ -defmodule WaferDriverElixirALE.GPIO.DispatcherTest do - use ExUnit.Case, async: true - alias Wafer.Driver.ElixirALE.GPIO.Dispatcher, as: Dispatcher - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.InterruptRegistry, as: IR - import Mimic - @moduledoc false - - setup do - Supervisor.terminate_child(Wafer.Supervisor, IR) - Supervisor.restart_child(Wafer.Supervisor, IR) - {:ok, []} - end - - describe "handle_call/3" do - test "enabling rising interrupts" do - conn = conn() - - Wrapper - |> expect(:set_int, 1, fn pid, pin_condition -> - assert pid == conn.pid - assert pin_condition == :rising - :ok - end) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:enable, conn, :rising}, nil, state()) - end - - test "enabling falling interrupts" do - conn = conn() - - Wrapper - |> expect(:set_int, 1, fn pid, pin_condition -> - assert pid == conn.pid - assert pin_condition == :falling - :ok - end) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:enable, conn, :falling}, nil, state()) - end - - test "enabling both interrupts" do - conn = conn() - - Wrapper - |> expect(:set_int, 1, fn pid, pin_condition -> - assert pid == conn.pid - assert pin_condition == :both - :ok - end) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:enable, conn, :both}, nil, state()) - end - - test "disabling rising interrupts" do - conn = conn() - - Wrapper - |> stub(:set_int, fn _, _ -> :ok end) - - Dispatcher.handle_call({:enable, conn, :rising}, nil, state()) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:disable, conn, :rising}, nil, state()) - end - - test "disabling falling interrupts" do - conn = conn() - - Wrapper - |> stub(:set_int, fn _, _ -> :ok end) - - Dispatcher.handle_call({:enable, conn, :falling}, nil, state()) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:disable, conn, :falling}, nil, state()) - end - - test "disabling both interrupts" do - conn = conn() - - Wrapper - |> stub(:set_int, fn _, _ -> :ok end) - - Dispatcher.handle_call({:enable, conn, :both}, nil, state()) - - assert {:reply, {:ok, _conn}, _state} = - Dispatcher.handle_call({:disable, conn, :both}, nil, state()) - end - end - - describe "handle_info/2" do - test "publishing rising interrupts" do - Wrapper - |> stub(:set_int, fn _, _ -> :ok end) - - {:reply, {:ok, _conn}, state} = - Dispatcher.handle_call({:enable, conn(), :both}, nil, state()) - - IR - |> expect(:publish, 1, fn _key, condition -> - assert condition == :rising - {:ok, []} - end) - - {:noreply, _state} = Dispatcher.handle_info({:gpio_interrupt, 1, :rising}, state) - end - - test "publishing falling interrupts" do - Wrapper - |> stub(:set_int, fn _, _ -> :ok end) - - {:reply, {:ok, _conn}, state} = - Dispatcher.handle_call( - {:enable, conn(), :both}, - nil, - state() - ) - - IR - |> expect(:publish, 1, fn _key, condition -> - assert condition == :falling - {:ok, []} - end) - - {:noreply, _state} = Dispatcher.handle_info({:gpio_interrupt, 1, :falling}, state) - end - end - - defp conn(opts \\ []), do: Enum.into(opts, %{pin: pin(), pid: self()}) - defp state(opts \\ []), do: Enum.into(opts, %{}) - defp pin, do: 1 -end diff --git a/test/drivers/elixir_ale_gpio_test.exs b/test/drivers/elixir_ale_gpio_test.exs deleted file mode 100644 index 1573da3..0000000 --- a/test/drivers/elixir_ale_gpio_test.exs +++ /dev/null @@ -1,116 +0,0 @@ -defmodule WaferDriverElixirALE.GPIOTest do - use ExUnit.Case, async: true - use Mimic - alias Wafer.Driver.ElixirALE.GPIO, as: Subject - alias Wafer.Driver.ElixirALE.GPIO.Dispatcher, as: Dispatcher - alias Wafer.Driver.ElixirALE.GPIO.Wrapper - alias Wafer.GPIO, as: GPIO - alias Wafer.Release, as: Release - @moduledoc false - - describe "acquire/1" do - test "opens the pin and creates the conn" do - Wrapper - |> expect(:start_link, 1, fn pin, direction, opts -> - assert pin == 1 - assert direction == :output - assert opts == [] - {:ok, self()} - end) - - assert {:ok, %Subject{}} = Subject.acquire(pin: 1, direction: :out) - end - - test "returns an error when the pin is not specified" do - assert {:error, _} = Subject.acquire([]) - end - end - - describe "Release.release/1" do - test "closes the pin" do - conn = conn() - - Wrapper - |> expect(:release, 1, fn pid -> - assert pid == conn.pid - :ok - end) - - assert :ok = Release.release(conn) - end - end - - describe "GPIO.read/1" do - test "can read the pin value" do - conn = conn() - - Wrapper - |> expect(:read, 1, fn pid -> - assert pid == conn.pid - 0 - end) - - assert {:ok, 0} = GPIO.read(conn) - end - end - - describe "GPIO.write/2" do - test "can set the pin value" do - conn = conn() - - Wrapper - |> expect(:write, 1, fn pid, value -> - assert pid == conn.pid - assert value == 1 - :ok - end) - - assert {:ok, %Subject{}} = GPIO.write(conn, 1) - end - end - - describe "GPIO.direction/2" do - test "is not supported" do - assert {:error, :not_supported} = GPIO.direction(conn(), :in) - end - end - - describe "GPIO.enable_interrupt/2" do - test "subscribes the conn to interrupts" do - conn = conn() - - Dispatcher - |> expect(:enable, 1, fn conn1, pin_condition, _metadata -> - assert conn1 == conn - assert pin_condition == :rising - :ok - end) - - assert :ok = GPIO.enable_interrupt(conn, :rising) - end - end - - describe "GPIO.disable_interrupt/2" do - test "unsubscribes the conn from interrupts" do - conn = conn() - - Dispatcher - |> expect(:disable, 1, fn conn1, pin_condition -> - assert conn1 == conn - assert pin_condition == :rising - :ok - end) - - assert :ok = GPIO.disable_interrupt(conn, :rising) - end - end - - describe "GPIO.pull_mode/2" do - test "is not supported" do - assert {:error, :not_supported} = GPIO.pull_mode(conn(), :pull_up) - end - end - - defp conn(opts \\ []), do: struct(%Subject{pin: pin(), pid: self()}, opts) - defp pin, do: 1 -end diff --git a/test/drivers/elixir_ale_i2c_test.exs b/test/drivers/elixir_ale_i2c_test.exs deleted file mode 100644 index c764904..0000000 --- a/test/drivers/elixir_ale_i2c_test.exs +++ /dev/null @@ -1,207 +0,0 @@ -defmodule WaferElixirALE.I2CTest do - use ExUnit.Case, async: true - use Mimic - alias Wafer.Chip - alias Wafer.Driver.ElixirALE.I2C, as: Subject - alias Wafer.Driver.ElixirALE.I2C.Wrapper - alias Wafer.{I2C, Release} - @moduledoc false - - describe "acquire/1" do - test "opens the bus and verifies that the device is present" do - buspid = self() - busname = "i2c-1" - address = 0x13 - - Wrapper - |> expect(:start_link, 1, fn bus, address -> - assert bus == busname - assert address == 0x13 - {:ok, buspid} - end) - |> expect(:detect_devices, 1, fn pid -> - assert buspid == pid - [address] - end) - - assert {:ok, %Subject{}} = Subject.acquire(bus_name: busname, address: address) - end - - test "when the device is not present on the bus" do - buspid = self() - busname = "i2c-1" - address = 0x13 - - Wrapper - |> expect(:start_link, 1, fn bus, address -> - assert bus == busname - assert address == 0x13 - {:ok, buspid} - end) - |> expect(:detect_devices, 1, fn pid -> - assert buspid == pid - [] - end) - - assert {:error, _reason} = Subject.acquire(bus_name: busname, address: address) - end - - test "when the device is not present on the bus but an override is forced" do - buspid = self() - busname = "i2c-1" - address = 0x13 - - Wrapper - |> expect(:start_link, 1, fn bus, address -> - assert bus == busname - assert address == 0x13 - {:ok, buspid} - end) - |> expect(:detect_devices, 1, fn pid -> - assert buspid == pid - [] - end) - - assert {:ok, %Subject{}} = Subject.acquire(bus_name: busname, address: address, force: true) - end - - test "when the bus name is not specified it returns an error" do - assert {:error, _} = Subject.acquire(address: 0x13) - end - - test "when the address is not specified it returns an error" do - assert {:error, _} = Subject.acquire(bus_name: "i2c-1") - end - end - - describe "Release.release/1" do - test "closes the bus connection" do - conn = conn() - - Wrapper - |> expect(:release, 1, fn pid -> - assert pid == conn.pid - :ok - end) - - assert :ok = Release.release(conn) - end - end - - describe "Chip.read_register/3" do - test "reads from the device's register" do - conn = conn() - - Wrapper - |> expect(:write_read, 1, fn pid, data, bytes -> - assert pid == conn.pid - assert data == <<0>> - assert bytes == 2 - <<0, 0>> - end) - - assert {:ok, <<0, 0>>} = Chip.read_register(conn, 0, 2) - end - end - - describe "Chip.write_register/3" do - test "writes to the device's register" do - conn = conn() - - Wrapper - |> expect(:write, 1, fn pid, data -> - assert pid == conn.pid - assert data == <<1, 2, 3>> - :ok - end) - - assert {:ok, %Subject{}} = Chip.write_register(conn, 1, <<2, 3>>) - end - end - - describe "Chip.swap_register/3" do - test "swaps the device's register value for a new value, returning the old value" do - conn = conn() - - Wrapper - |> expect(:write_read, 1, fn pid, data, bytes -> - assert pid == conn.pid - assert data == <<0>> - assert bytes == 2 - <<0, 0>> - end) - - Wrapper - |> expect(:write, 1, fn pid, data -> - assert pid == conn.pid - assert data == <<0, 1, 1>> - :ok - end) - - assert {:ok, <<0, 0>>, %Subject{}} = Chip.swap_register(conn, 0, <<1, 1>>) - end - end - - describe "I2C.read/2" do - test "reads from the device" do - conn = conn() - - Wrapper - |> expect(:read, 1, fn pid, bytes -> - assert pid == conn.pid - assert bytes == 2 - <<0, 0>> - end) - - assert {:ok, <<0, 0>>} = I2C.read(conn, 2) - end - end - - describe "I2C.write/2" do - test "it writes to the device" do - conn = conn() - - Wrapper - |> expect(:write, 1, fn pid, data -> - assert pid == conn.pid - assert data == <<0, 0>> - :ok - end) - - assert {:ok, %Subject{}} = I2C.write(conn, <<0, 0>>) - end - end - - describe "I2C.write_read/3" do - test "it writes to then reads from the device" do - conn = conn() - - Wrapper - |> expect(:write_read, 1, fn pid, data, bytes -> - assert pid == conn.pid - assert data == <<1>> - assert bytes == 2 - - <<0, 0>> - end) - - assert {:ok, <<0, 0>>, %Subject{}} = I2C.write_read(conn, <<1>>, 2) - end - end - - describe "I2C.detect_devices/1" do - test "it detects devices" do - conn = conn() - - Wrapper - |> expect(:detect_devices, 1, fn pid -> - assert conn.pid == pid - [conn.address] - end) - - assert {:ok, [0x13]} = I2C.detect_devices(conn) - end - end - - defp conn, do: %Subject{pid: self(), bus: "i2c-1", address: 0x13} -end diff --git a/test/drivers/elixir_ale_spi_test.exs b/test/drivers/elixir_ale_spi_test.exs deleted file mode 100644 index be9613c..0000000 --- a/test/drivers/elixir_ale_spi_test.exs +++ /dev/null @@ -1,57 +0,0 @@ -defmodule WaferElixirALE.SPITest do - use ExUnit.Case, async: true - use Mimic - alias Wafer.Driver.ElixirALE.SPI, as: Subject - alias Wafer.Driver.ElixirALE.SPI.Wrapper - alias Wafer.{Release, SPI} - @moduledoc false - - describe "acquire/1" do - test "opens the bus" do - Wrapper - |> expect(:start_link, 1, fn bus, spi_opts, opts -> - assert bus == "spidev0.0" - assert spi_opts == [] - assert opts == [] - {:ok, self()} - end) - - assert {:ok, %Subject{}} = Subject.acquire(bus_name: "spidev0.0") - end - - test "when the bus name is not specified it returns an error" do - assert {:error, _} = Subject.acquire([]) - end - end - - describe "Release.release/1" do - test "closes the bus connection" do - conn = conn() - - Wrapper - |> expect(:release, 1, fn pid -> - assert pid == conn.pid - :ok - end) - - assert :ok = Release.release(conn) - end - end - - describe "SPI.transfer/2" do - test "transfers data to and from the bus" do - conn = conn() - - Wrapper - |> expect(:transfer, 1, fn pid, data -> - assert pid == conn.pid - assert data == <<0, 0>> - <<1, 1>> - end) - - assert {:ok, <<1, 1>>, %Subject{}} = SPI.transfer(conn, <<0, 0>>) - end - end - - defp conn, do: %Subject{pid: self(), bus: "spidev0.0"} -end diff --git a/test/test_helper.exs b/test/test_helper.exs index 56997b9..0603ef8 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -3,10 +3,6 @@ Mimic.copy(Wafer.Driver.Circuits.GPIO.Wrapper) Mimic.copy(Wafer.Driver.Circuits.GPIO.Dispatcher) Mimic.copy(Wafer.Driver.Circuits.I2C.Wrapper) Mimic.copy(Wafer.Driver.Circuits.SPI.Wrapper) -Mimic.copy(Wafer.Driver.ElixirALE.GPIO.Wrapper) -Mimic.copy(Wafer.Driver.ElixirALE.GPIO.Dispatcher) -Mimic.copy(Wafer.Driver.ElixirALE.I2C.Wrapper) -Mimic.copy(Wafer.Driver.ElixirALE.SPI.Wrapper) Mimic.copy(Wafer.InterruptRegistry) ExUnit.start()