Skip to content

Commit 28c7507

Browse files
committed
Support returning I2C errors from reads
This commit just adds support for returning errors from read and write_read. The I2C write return value is still always :ok in this commit. All reads are still always successful.
1 parent b8b199e commit 28c7507

8 files changed

Lines changed: 43 additions & 37 deletions

File tree

lib/circuits_sim/device/ads7138.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ defmodule CircuitsSim.Device.ADS7138 do
3838
# for reading, but we'll include it here just in case.
3939
last = state.current + count
4040
result = for reg <- state.current..last, into: <<>>, do: read_register(state, reg)
41-
{result, %{state | current: last}}
41+
{{:ok, result}, %{state | current: last}}
4242
end
4343

4444
@impl I2CDevice
@@ -63,13 +63,13 @@ defmodule CircuitsSim.Device.ADS7138 do
6363

6464
@impl I2CDevice
6565
def write_read(state, <<@single_register_read, register>>, 1) do
66-
{read_register(state, register), %{state | current: register}}
66+
{{:ok, read_register(state, register)}, %{state | current: register}}
6767
end
6868

6969
def write_read(state, <<@continuous_register_read, register>>, count) do
7070
last = state.current + count
7171
result = for reg <- state.current..last, into: <<>>, do: read_register(state, reg)
72-
{result, %{state | current: register}}
72+
{{:ok, result}, %{state | current: register}}
7373
end
7474

7575
@impl I2CDevice

lib/circuits_sim/device/aht20.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ defmodule CircuitsSim.Device.AHT20 do
4141
@impl I2CDevice
4242
def read(%{current: :measure} = state, count) do
4343
result = raw_sample(state) |> trim_pad(count)
44-
{result, %{state | current: nil}}
44+
{{:ok, result}, %{state | current: nil}}
4545
end
4646

4747
def read(state, count) do
48-
{:binary.copy(<<0>>, count), %{state | current: nil}}
48+
{{:ok, :binary.copy(<<0>>, count)}, %{state | current: nil}}
4949
end
5050

5151
@impl I2CDevice
@@ -56,7 +56,7 @@ defmodule CircuitsSim.Device.AHT20 do
5656

5757
@impl I2CDevice
5858
def write_read(state, _to_write, read_count) do
59-
{:binary.copy(<<0>>, read_count), %{state | current: :reset}}
59+
{{:ok, :binary.copy(<<0>>, read_count)}, %{state | current: :reset}}
6060
end
6161

6262
defp trim_pad(x, count) when byte_size(x) >= count, do: :binary.part(x, 0, count)

lib/circuits_sim/device/sgp30.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,16 @@ defmodule CircuitsSim.Device.SGP30 do
7777
@impl I2CDevice
7878
def read(%{current: :iaq_measure} = state, count) do
7979
result = binary_for_measure(state) |> trim_pad(count)
80-
{result, %{state | current: nil}}
80+
{{:ok, result}, %{state | current: nil}}
8181
end
8282

8383
def read(%{current: :iaq_measure_raw} = state, count) do
8484
result = binary_for_measure_raw(state) |> trim_pad(count)
85-
{result, %{state | current: nil}}
85+
{{:ok, result}, %{state | current: nil}}
8686
end
8787

8888
def read(state, count) do
89-
{:binary.copy(<<0>>, count), %{state | current: nil}}
89+
{{:ok, :binary.copy(<<0>>, count)}, %{state | current: nil}}
9090
end
9191

9292
@impl I2CDevice
@@ -98,7 +98,7 @@ defmodule CircuitsSim.Device.SGP30 do
9898
@impl I2CDevice
9999
def write_read(state, <<0x36, 0x82>>, count) do
100100
result = binary_for_serial(state) |> trim_pad(count)
101-
{result, %{state | current: nil}}
101+
{{:ok, result}, %{state | current: nil}}
102102
end
103103

104104
def write_read(state, _to_write, read_count) do

lib/circuits_sim/device/sht4x.ex

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ defmodule CircuitsSim.Device.SHT4X do
7676

7777
@impl I2CDevice
7878
def read(%{current: :serial_number} = state, count) do
79-
new_state = binary_for_serial_number(state)
80-
{trim_pad(new_state.acc, count), %{new_state | current: nil, acc: <<>>}}
79+
state |> binary_for_serial_number() |> flush_read_to_result(count)
8180
end
8281

8382
def read(%{current: op} = state, count)
@@ -86,12 +85,15 @@ defmodule CircuitsSim.Device.SHT4X do
8685
:measure_medium_repeatability,
8786
:measure_low_repeatability
8887
] do
89-
new_state = raw_sample(state)
90-
{trim_pad(new_state.acc, count), %{new_state | current: nil, acc: <<>>}}
88+
state |> raw_sample() |> flush_read_to_result(count)
9189
end
9290

9391
def read(state, count) do
94-
{:binary.copy(<<0>>, count), %{state | current: nil}}
92+
flush_read_to_result(state, count)
93+
end
94+
95+
defp flush_read_to_result(state, count) do
96+
{{:ok, trim_pad(state.acc, count)}, %{state | current: nil, acc: <<>>}}
9597
end
9698

9799
@impl I2CDevice
@@ -103,7 +105,7 @@ defmodule CircuitsSim.Device.SHT4X do
103105

104106
@impl I2CDevice
105107
def write_read(state, _to_write, read_count) do
106-
{:binary.copy(<<0>>, read_count), %{state | current: nil}}
108+
{{:ok, :binary.copy(<<0>>, read_count)}, %{state | current: nil}}
107109
end
108110

109111
defp trim_pad(x, count) when byte_size(x) >= count, do: :binary.part(x, 0, count)

lib/circuits_sim/device/vcnl4040.ex

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ defmodule CircuitsSim.Device.VCNL4040 do
8686

8787
@impl I2CDevice
8888
def read(state, count) do
89-
{:binary.copy(<<0>>, count), state}
89+
{{:ok, :binary.copy(<<0>>, count)}, state}
9090
end
9191

9292
@impl I2CDevice
@@ -178,27 +178,27 @@ defmodule CircuitsSim.Device.VCNL4040 do
178178

179179
@impl I2CDevice
180180
def write_read(state, <<@ps_data_register>>, 2) do
181-
{<<state.proximity_raw::little-16>>, state}
181+
{{:ok, <<state.proximity_raw::little-16>>}, state}
182182
end
183183

184184
def write_read(state, <<@als_data_register>>, 2) do
185-
{<<state.ambient_light_raw::little-16>>, state}
185+
{{:ok, <<state.ambient_light_raw::little-16>>}, state}
186186
end
187187

188188
def write_read(state, <<@white_data_register>>, 2) do
189-
{<<state.white_light_raw::little-16>>, state}
189+
{{:ok, <<state.white_light_raw::little-16>>}, state}
190190
end
191191

192192
def write_read(state, <<@als_ps_interrupt_flag_register>>, 2) do
193-
{<<0x00, 0x00>>, state}
193+
{{:ok, <<0x00, 0x00>>}, state}
194194
end
195195

196196
def write_read(state, <<@cmd_device_id>>, 2) do
197-
{<<0x86, 0x01>>, state}
197+
{{:ok, <<0x86, 0x01>>}, state}
198198
end
199199

200200
def write_read(state, _value, read_count) do
201-
{:binary.copy(<<0>>, read_count), state}
201+
{{:ok, :binary.copy(<<0>>, read_count)}, state}
202202
end
203203

204204
@impl I2CDevice

lib/circuits_sim/device/veml7700.ex

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ defmodule CircuitsSim.Device.VEML7700 do
5757

5858
@impl I2CDevice
5959
def read(state, count) do
60-
{:binary.copy(<<0>>, count), state}
60+
{{:ok, :binary.copy(<<0>>, count)}, state}
6161
end
6262

6363
@impl I2CDevice
@@ -82,41 +82,41 @@ defmodule CircuitsSim.Device.VEML7700 do
8282
@impl I2CDevice
8383
def write_read(state, <<@cmd_als_config>>, read_count) do
8484
result = <<state.als_config::little-16>> |> trim_pad(read_count)
85-
{result, state}
85+
{{:ok, result}, state}
8686
end
8787

8888
def write_read(state, <<@cmd_als_threshold_high>>, read_count) do
8989
result = <<state.als_threshold_high>> |> trim_pad(read_count)
90-
{result, state}
90+
{{:ok, result}, state}
9191
end
9292

9393
def write_read(state, <<@cmd_als_threshold_low>>, read_count) do
9494
result = <<state.als_threshold_low::little-16>> |> trim_pad(read_count)
95-
{result, state}
95+
{{:ok, result}, state}
9696
end
9797

9898
def write_read(state, <<@cmd_als_power_saving>>, read_count) do
9999
result = <<state.als_power_saving::little-16>> |> trim_pad(read_count)
100-
{result, state}
100+
{{:ok, result}, state}
101101
end
102102

103103
def write_read(state, <<@cmd_als_output>>, read_count) do
104104
result = <<state.als_output::little-16>> |> trim_pad(read_count)
105-
{result, state}
105+
{{:ok, result}, state}
106106
end
107107

108108
def write_read(state, <<@cmd_white_output>>, read_count) do
109109
result = <<state.white_output::little-16>> |> trim_pad(read_count)
110-
{result, state}
110+
{{:ok, result}, state}
111111
end
112112

113113
def write_read(state, <<@cmd_interrupt_status>>, read_count) do
114114
result = <<state.interrupt_status::little-16>> |> trim_pad(read_count)
115-
{result, state}
115+
{{:ok, result}, state}
116116
end
117117

118118
def write_read(state, _to_write, read_count) do
119-
{:binary.copy(<<0>>, read_count), state}
119+
{{:ok, :binary.copy(<<0>>, read_count)}, state}
120120
end
121121

122122
defp trim_pad(x, count) when byte_size(x) >= count, do: :binary.part(x, 0, count)

lib/circuits_sim/i2c/i2c_device.ex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ defprotocol CircuitsSim.I2C.I2CDevice do
77

88
@doc """
99
Read count bytes
10+
11+
The first item in the returned tuple is what's returned from the original
12+
call to Circuits.I2C.read/2. Try to make the errors consistent with that
13+
function if possible.
1014
"""
11-
@spec read(t(), non_neg_integer()) :: {binary(), t()}
15+
@spec read(t(), non_neg_integer()) :: {{:ok, binary()} | {:error, any()}, t()}
1216
def read(dev, count)
1317

1418
@doc """
@@ -20,7 +24,7 @@ defprotocol CircuitsSim.I2C.I2CDevice do
2024
@doc """
2125
Write data to the device and immediately follow it with a read
2226
"""
23-
@spec write_read(t(), binary(), non_neg_integer()) :: {binary(), t()}
27+
@spec write_read(t(), binary(), non_neg_integer()) :: {{:ok, binary()} | {:error, any()}, t()}
2428
def write_read(dev, data, read_count)
2529

2630
@doc """

lib/circuits_sim/i2c/i2c_server.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ defmodule CircuitsSim.I2C.I2CServer do
108108
@impl GenServer
109109
def handle_call({:read, count}, _from, state) do
110110
{result, new_state} = do_read(state, count)
111-
{:reply, {:ok, result}, new_state}
111+
{:reply, result, new_state}
112112
end
113113

114114
def handle_call({:write, data}, _from, state) do
@@ -118,7 +118,7 @@ defmodule CircuitsSim.I2C.I2CServer do
118118

119119
def handle_call({:write_read, data, read_count}, _from, state) do
120120
{result, new_state} = do_write_read(state, IO.iodata_to_binary(data), read_count)
121-
{:reply, {:ok, result}, new_state}
121+
{:reply, result, new_state}
122122
end
123123

124124
def handle_call(:render, _from, state) do
@@ -175,7 +175,7 @@ defmodule CircuitsSim.I2C.I2CServer do
175175

176176
defp simple_read(state, 0, acc) do
177177
result = acc |> Enum.reverse() |> :binary.list_to_bin()
178-
{result, state}
178+
{{:ok, result}, state}
179179
end
180180

181181
defp simple_read(state, count, acc) do

0 commit comments

Comments
 (0)