Skip to content

Commit 6d63614

Browse files
committed
Add experimental I2C failure support for SHT4x's
This seems useful to extend more generally as well. It wouldn't remove a device-specific implementation since some devices get unhappy and start returning errors when you don't treat them right. That might be interesting. The goal of this is to get some experience before doing anything more substantial.
1 parent 28c7507 commit 6d63614

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

lib/circuits_sim/device/sht4x.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ defmodule CircuitsSim.Device.SHT4X do
1515
humidity_rh: 30.0,
1616
temperature_c: 22.2,
1717
crc_injection_count: 0,
18+
broken: nil,
1819
acc: <<>>
1920

2021
@type t() :: %__MODULE__{
@@ -23,6 +24,7 @@ defmodule CircuitsSim.Device.SHT4X do
2324
humidity_rh: float(),
2425
temperature_c: float(),
2526
crc_injection_count: non_neg_integer(),
27+
broken: nil | {:error, any()},
2628
acc: binary()
2729
}
2830

@@ -69,12 +71,27 @@ defmodule CircuitsSim.Device.SHT4X do
6971
I2CServer.send_message(bus_name, address, {:inject_crc_errors, count})
7072
end
7173

74+
@doc """
75+
Experimental API to return I2C errors on read/read_writes
76+
77+
Set the 3rd argument to an error tuple to be returned or `nil` to work
78+
normally.
79+
"""
80+
@spec set_broken(String.t(), Circuits.I2C.address(), nil | {:error, any()}) :: :ok
81+
def set_broken(bus_name, address, broken) do
82+
I2CServer.send_message(bus_name, address, {:set_broken, broken})
83+
end
84+
7285
## protocol implementation
7386

7487
defimpl I2CDevice do
7588
@crc_alg :cerlc.init(:crc8_sensirion)
7689

7790
@impl I2CDevice
91+
def read(%{broken: result} = state, _count) when is_tuple(result) do
92+
{result, state}
93+
end
94+
7895
def read(%{current: :serial_number} = state, count) do
7996
state |> binary_for_serial_number() |> flush_read_to_result(count)
8097
end
@@ -104,6 +121,10 @@ defmodule CircuitsSim.Device.SHT4X do
104121
def write(state, _), do: state
105122

106123
@impl I2CDevice
124+
def write_read(%{broken: result} = state, _to_write, _read_count) when is_tuple(result) do
125+
{result, state}
126+
end
127+
107128
def write_read(state, _to_write, read_count) do
108129
{{:ok, :binary.copy(<<0>>, read_count)}, %{state | current: nil}}
109130
end
@@ -131,6 +152,10 @@ defmodule CircuitsSim.Device.SHT4X do
131152
{:ok, %{state | crc_injection_count: count}}
132153
end
133154

155+
def handle_message(state, {:set_broken, value}) do
156+
{:ok, %{state | broken: value}}
157+
end
158+
134159
defp binary_for_serial_number(state) do
135160
state |> add_crcs(<<state.serial_number::32>>)
136161
end

0 commit comments

Comments
 (0)