# `CircuitsSim.I2C.I2CDevice`
[🔗](https://github.com/elixir-circuits/circuits_sim/blob/v0.1.2/lib/circuits_sim/i2c/i2c_device.ex#L1)

A protocol for I2C devices

See `Circuits.I2C.SimpleI2CDevice` if you have a simple register-based I2C device.

# `t`

```elixir
@type t() :: term()
```

All the types that implement this protocol.

# `handle_message`

```elixir
@spec handle_message(t(), any()) :: {any(), t()}
```

Handle an user message

User messages are used to modify the state of the simulated device outside of
I2C. This can be used to simulate real world changes like temperature changes
affecting a simulated temperature sensor. Another use is as a hook for getting
internal state.

# `read`

```elixir
@spec read(t(), non_neg_integer()) :: {{:ok, binary()} | {:error, any()}, t()}
```

Read count bytes

The first item in the returned tuple is what's returned from the original
call to Circuits.I2C.read/2. Try to make the errors consistent with that
function if possible.

# `render`

```elixir
@spec render(t()) :: IO.ANSI.ansidata()
```

Return the internal state as ASCII art

# `write`

```elixir
@spec write(t(), binary()) :: t()
```

Write data to the device

# `write_read`

```elixir
@spec write_read(t(), binary(), non_neg_integer()) ::
  {{:ok, binary()} | {:error, any()}, t()}
```

Write data to the device and immediately follow it with a read

---

*Consult [api-reference.md](api-reference.md) for complete listing*
