Skip to content

Commit 3295dc1

Browse files
authored
Merge pull request #4 from infinity-aps/autodetect
Support multiple chip processes and chip detection
2 parents e5a6e56 + 6be2a6b commit 3295dc1

2 files changed

Lines changed: 119 additions & 145 deletions

File tree

lib/rfm69.ex

Lines changed: 86 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,142 @@
11
defmodule RFM69 do
22
use Bitwise
33

4-
@device RFM69.Device
4+
alias RFM69.Device
5+
alias RFM69.Configuration
6+
57
@moduledoc false
68
@fifo_size 66
79
@transfer_sleep trunc(@fifo_size / 4)
810

911
@doc """
1012
Sets the base frequency of the RFM69 chip in MHz
1113
"""
12-
@spec set_base_frequency(pos_integer) :: {:ok}
13-
def set_base_frequency(mhz) do
14-
@device.write_frequency(trunc(mhz * 1_000_000))
14+
@frf_location 0x07
15+
@spec set_base_frequency(Device.t, pos_integer) :: {:ok}
16+
def set_base_frequency(%Device{name: name}, mhz) do
17+
frequency_in_hz = trunc(mhz * 1_000_000)
18+
register_values = Configuration.frequency_to_registers(frequency_in_hz)
19+
register_bytes = <<register_values::24>>
20+
:ok = GenServer.call(name, {:write_burst, @frf_location, register_bytes})
21+
{:ok}
1522
end
1623

1724
@doc """
1825
reads a frame of binary data from the chip's FIFO queue
1926
"""
20-
@spec read(non_neg_integer) :: {:ok, %{data: binary, rssi: number}} | {:error, any()}
21-
def read(timeout_ms) do
22-
set_auto_modes([])
23-
set_mode(:receiver)
24-
@device.await_interrupt()
27+
@spec read(Device.t, non_neg_integer) :: {:ok, %{data: binary, rssi: number}} | {:error, any()}
28+
def read(%Device{name: name}, timeout_ms) do
29+
set_auto_modes(name, [])
30+
set_mode(name, :receiver)
31+
GenServer.call(name, {:await_interrupt})
2532

2633
result =
2734
receive do
2835
{:ok, :interrupt_received} ->
29-
rssi = read_rssi()
30-
bytes = read_until_null(<<>>)
36+
rssi = read_rssi(name)
37+
bytes = read_until_null(name, <<>>)
3138
{:ok, %{data: bytes, rssi: rssi}}
3239
after
3340
timeout_ms ->
34-
@device.cancel_interrupt()
41+
GenServer.call(name, {:cancel_interrupt})
3542
{:error, :timeout}
3643
end
3744

38-
set_mode(:sleep)
45+
set_mode(name, :sleep)
3946
result
4047
end
4148

4249
@doc """
4350
Writes a frame of binary data to the FIFO queue
4451
"""
45-
@spec write(binary, pos_integer, non_neg_integer, non_neg_integer, boolean) :: {:ok, <<>>}
46-
def write(packet_bytes, repetitions, repetition_delay, timeout_ms, initial \\ true) do
52+
@spec write(Device.t, binary, pos_integer, non_neg_integer, non_neg_integer, boolean) :: {:ok, <<>>}
53+
def write(chip = %Device{name: name}, packet_bytes, repetitions, repetition_delay, timeout_ms, initial \\ true) do
4754
if initial == true do
48-
clear_fifo()
49-
set_mode(:standby)
55+
clear_fifo(name)
56+
set_mode(name, :standby)
5057
end
5158

5259
case repetitions do
5360
r when r >= 1 ->
54-
_write(packet_bytes, timeout_ms)
61+
_write(name, packet_bytes, timeout_ms)
5562
:timer.sleep(repetition_delay)
56-
write(packet_bytes, repetitions - 1, repetition_delay, timeout_ms, false)
63+
write(chip, packet_bytes, repetitions - 1, repetition_delay, timeout_ms, false)
5764

5865
0 ->
59-
set_mode(:sleep)
66+
set_mode(name, :sleep)
6067
{:ok, ""}
6168
end
6269
end
6370

6471
@doc """
6572
Writes the given binary data to the FIFO queue and waits for the response.
6673
"""
67-
@spec write_and_read(binary, non_neg_integer) :: {:ok, %{data: binary, rssi: number}} | {:error, any()}
68-
def write_and_read(packet_bytes, timeout_ms) do
69-
write(packet_bytes, 1, 0, timeout_ms)
70-
read(timeout_ms)
74+
@spec write_and_read(Device.t, binary, non_neg_integer) :: {:ok, %{data: binary, rssi: number}} | {:error, any()}
75+
def write_and_read(chip = %Device{}, packet_bytes, timeout_ms) do
76+
write(chip, packet_bytes, 1, 0, timeout_ms)
77+
read(chip, timeout_ms)
78+
end
79+
80+
@spec clear_buffers(Device.t) :: :ok
81+
def clear_buffers(%Device{name: name}) do
82+
clear_fifo(name)
7183
end
7284

73-
@spec clear_buffers() :: :ok
74-
def clear_buffers do
75-
clear_fifo()
85+
@doc """
86+
Writes a full configuration struct to the registers on the chip.
87+
"""
88+
@configuration_start 0x01
89+
@spec write_configuration(Device.t, RFM69.Configuration.t) :: :ok
90+
def write_configuration(%Device{name: name}, rf_config = %Configuration{}) do
91+
configuration_bytes = Configuration.to_binary(rf_config)
92+
:ok = GenServer.call(name, {:write_burst, @configuration_start, configuration_bytes})
7693
end
7794

78-
defp _write(packet_bytes, _timeout_ms) do
95+
defp _write(name, packet_bytes, _timeout_ms) do
7996
modes = [:enter_condition_fifo_not_empty, :exit_condition_fifo_empty, :intermediate_mode_tx]
80-
set_auto_modes(modes)
81-
transmit(packet_bytes, @fifo_size)
97+
set_auto_modes(name, modes)
98+
transmit(name, packet_bytes, @fifo_size)
8299
end
83100

84-
defp read_until_null(data) do
85-
case @device.read_single(0x00) do
86-
{:ok, 0x00} -> data
87-
{:ok, byte} -> read_until_null(data <> <<byte::8>>)
101+
defp read_until_null(name, data) do
102+
case GenServer.call(name, {:read_burst, 0x00, 1}) do
103+
{:ok, <<0x00::8>>} -> data
104+
{:ok, <<byte::8>>} -> read_until_null(name, data <> <<byte::8>>)
88105
end
89106
end
90107

91-
defp transmit(bytes, available_buffer_bytes) when byte_size(bytes) <= available_buffer_bytes do
92-
_transmit(bytes)
93-
wait_for_mode(:standby)
108+
defp transmit(name, bytes, available_buffer_bytes) when byte_size(bytes) <= available_buffer_bytes do
109+
_transmit(name, bytes)
110+
wait_for_mode(name, :standby)
94111
end
95112

96-
defp transmit(bytes, available_buffer_bytes) do
113+
defp transmit(name, bytes, available_buffer_bytes) do
97114
<<transmit_now::binary-size(available_buffer_bytes), transmit_later::binary>> = bytes
98-
available_buffer_bytes = _transmit(transmit_now)
99-
transmit(transmit_later, available_buffer_bytes)
115+
available_buffer_bytes = _transmit(name, transmit_now)
116+
transmit(name, transmit_later, available_buffer_bytes)
100117
end
101118

102-
defp _transmit(bytes) do
103-
@device.write_burst(0x00, bytes)
119+
defp _transmit(name, bytes) do
120+
GenServer.call(name, {:write_burst, 0x00, bytes})
104121
:timer.sleep(@transfer_sleep)
105-
wait_for_buffer_to_become_available()
122+
wait_for_buffer_to_become_available(name)
106123
end
107124

108125
@reg_irq_flags2 0x28
109126
@fifo_overrun 0x10
110-
defp clear_fifo do
111-
@device.write_single(@reg_irq_flags2, @fifo_overrun)
127+
defp clear_fifo(name) do
128+
GenServer.call(name, {:write_burst, @reg_irq_flags2, <<@fifo_overrun::8>>})
112129
end
113130

114131
@fifo_level 0x20
115-
defp fifo_threshold_exceeded?() do
116-
{:ok, byte} = @device.read_single(@reg_irq_flags2)
132+
defp fifo_threshold_exceeded?(name) do
133+
{:ok, <<byte::8>>} = GenServer.call(name, {:read_burst, @reg_irq_flags2, 1})
117134
(byte &&& @fifo_level) != 0x00
118135
end
119136

120-
defp wait_for_buffer_to_become_available do
121-
case fifo_threshold_exceeded?() do
122-
true -> wait_for_buffer_to_become_available()
137+
defp wait_for_buffer_to_become_available(name) do
138+
case fifo_threshold_exceeded?(name) do
139+
true -> wait_for_buffer_to_become_available(name)
123140
false -> nil
124141
end
125142
end
@@ -137,32 +154,32 @@ defmodule RFM69 do
137154
transmitter: 0x0C,
138155
receiver: 0x10
139156
}
140-
defp set_mode(mode) do
157+
defp set_mode(name, mode) do
141158
mode = Map.get(@modes, mode)
142-
current_mode = get_mode()
159+
current_mode = get_mode(name)
143160

144161
case mode do
145162
^current_mode -> true
146163
_ ->
147-
@device.write_single(@reg_op_mode, mode)
148-
wait_for_mode_ready(mode)
164+
GenServer.call(name, {:write_burst, @reg_op_mode, <<mode::8>>})
165+
wait_for_mode_ready(name, mode)
149166
end
150167
end
151168

152-
defp get_mode do
153-
{:ok, byte} = @device.read_single(@reg_op_mode)
169+
defp get_mode(name) do
170+
{:ok, <<byte>>} = GenServer.call(name, {:read_burst, @reg_op_mode, 1})
154171
byte
155172
end
156173

157-
defp wait_for_mode(mode) do
174+
defp wait_for_mode(name, mode) do
158175
mode = Map.get(@modes, mode)
159-
_wait_for_mode(mode)
176+
_wait_for_mode(name, mode)
160177
end
161178

162-
defp _wait_for_mode(mode) do
163-
if get_mode() != mode do
179+
defp _wait_for_mode(name, mode) do
180+
if get_mode(name) != mode do
164181
:timer.sleep(1)
165-
_wait_for_mode(mode)
182+
_wait_for_mode(name, mode)
166183
end
167184
end
168185

@@ -172,31 +189,31 @@ defmodule RFM69 do
172189
exit_condition_fifo_empty: 0x04,
173190
intermediate_mode_tx: 0x03
174191
}
175-
defp set_auto_modes(modes) do
192+
defp set_auto_modes(name, modes) do
176193
register_value =
177194
modes
178195
|> Enum.map(fn mode -> @auto_modes[mode] end)
179196
|> Enum.reduce(0x00, &(&1 ||| &2))
180197

181-
@device.write_single(@reg_auto_modes, register_value)
198+
GenServer.call(name, {:write_burst, @reg_auto_modes, <<register_value::8>>})
182199
end
183200

184201
@reg_irq_flags1 0x27
185202
@mode_ready 0x80
186-
defp wait_for_mode_ready(mode) do
187-
{:ok, current_mode} = @device.read_single(@reg_op_mode)
188-
{:ok, irq_flags1} = @device.read_single(@reg_irq_flags1)
203+
defp wait_for_mode_ready(name, mode) do
204+
{:ok, <<current_mode>>} = GenServer.call(name, {:read_burst, @reg_op_mode, 1})
205+
{:ok, <<irq_flags1>>} = GenServer.call(name, {:read_burst, @reg_irq_flags1, 1})
189206
mode_ready = (irq_flags1 &&& @mode_ready) != 0x00
190207

191208
case current_mode == mode && mode_ready do
192209
true -> true
193-
false -> wait_for_mode_ready(mode)
210+
false -> wait_for_mode_ready(name, mode)
194211
end
195212
end
196213

197214
@reg_rssi_val 0x24
198-
defp read_rssi do
199-
{:ok, <<raw_rssi::8>>} = @device.read_burst(@reg_rssi_val, 1)
215+
defp read_rssi(name) do
216+
{:ok, <<raw_rssi::8>>} = GenServer.call(name, {:read_burst, @reg_rssi_val, 1})
200217
-1 * trunc(raw_rssi) / 2
201218
end
202219
end

0 commit comments

Comments
 (0)