Wafer.Chip protocol (wafer v1.0.2)

A Chip is a physical peripheral with registers which can be read from and written to.

Rather than interacting with this protocol directly, it's a lot easier to use the macros in Wafer.Registers to do it for you.

deriving

Deriving

If you're implementing your own Conn type which simply delegates to one of the lower level drivers then you can derive this protocol automatically:

defmodule MyConnection do
  @derive Wafer.Chip
  defstruct [:conn]
end

If your type uses a key other than conn for the inner connection you can specify it while deriving:

defmodule MyConnection do
  @derive {Wafer.Chip, key: :i2c_conn}
  defstruct [:i2c_conn]
end

a-note-on-spi-devices

A note on SPI devices

You will have to manually implement this protocol for SPI devices as there is no conventional way to read and write registers over SPI and every device has their own way of implementing an SPI instruction set.

Link to this section Summary

Types

t()

All the types that implement this protocol.

Functions

Read the register at the specified address.

Perform a swap with the register at the specified address. With some drivers this is atomic, and with others it is implemented as a register read followed by a write.

Write to the register at the specified address.

Link to this section Types

Specs

bytes() :: non_neg_integer()
Link to this type

register_address()

Specs

register_address() :: non_neg_integer()

Specs

t() :: term()

All the types that implement this protocol.

Link to this section Functions

Link to this function

read_register(conn, register_address, bytes)

Specs

read_register(Wafer.Conn.t(), register_address(), bytes()) ::
  {:ok, data :: binary()} | {:error, reason :: any()}

Read the register at the specified address.

arguments

Arguments

  • conn a type which implements the Wafer.Conn behaviour.
  • register_address the address of the register to read from.
  • bytes the number of bytes to read from the register.

example

Example

iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c-1", address: 0x68)
...> Chip.read_register(conn, 0, 1)
{:ok, <<0>>}
Link to this function

swap_register(conn, register_address, new_data)

Specs

swap_register(Wafer.Conn.t(), register_address(), new_data :: binary()) ::
  {:ok, data :: binary(), t()} | {:error, reason :: any()}

Perform a swap with the register at the specified address. With some drivers this is atomic, and with others it is implemented as a register read followed by a write.

arguments

Arguments

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

returns

Returns

The data that was previously in the register.

example

Example

iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c", address: 0x68)
...> Chip.swap_register(conn, 0, <<1>>)
{:ok, <<0>>, conn}
Link to this function

write_register(conn, register_address, data)

Specs

write_register(Wafer.Conn.t(), register_address(), data :: binary()) ::
  {:ok, t()} | {:error, reason :: any()}

Write to the register at the specified address.

arguments

Arguments

  • conn a type which implements the Wafer.Conn behaviour.
  • register_address the address of the register to write to.
  • data a bitstring or binary of data to write to the register.

example

Example

iex> {:ok, conn} = ElixirALE.I2C.acquire(bus: "i2c", address: 0x68)
...> Chip.write_register(conn, 0, <<0>>)
{:ok, conn}