Question: Considering Wafer...for NRF24 Driver #1

Closed
opened 2020-05-07 07:46:08 +12:00 by kitplummer · 44 comments
kitplummer commented 2020-05-07 07:46:08 +12:00 (Migrated from gitlab.com)

Hey, more of a question than issue. I'm looking at the nrf24 radio, and notice there isn't first-class support within the Nerves ecosystem. My need is really simple (rx-only), but thinking about "porting" a Python/CircuitPython driver to Elixir, and found Wafer. The radio is SPI plus GPIO for both control and optional interrupt. Do you think this would be a decent fit for this potential project? Fair warning I'm also new to all this (Elixir, Nerves and the hardware stuff) but am willing to bite into it.

Hey, more of a question than issue. I'm looking at the nrf24 radio, and notice there isn't first-class support within the Nerves ecosystem. My need is really simple (rx-only), but thinking about "porting" a Python/CircuitPython driver to Elixir, and found Wafer. The radio is SPI plus GPIO for both control and optional interrupt. Do you think this would be a decent fit for this potential project? Fair warning I'm also new to all this (Elixir, Nerves and the hardware stuff) but am willing to bite into it.
kitplummer commented 2020-05-07 07:46:24 +12:00 (Migrated from gitlab.com)

changed title from Question: Considering Wafer... to Question: Considering Wafer...{+for NRF24 Driver+}

changed title from **Question: Considering Wafer...** to **Question: Considering Wafer...{+for NRF24 Driver+}**
jimsy commented 2020-05-07 07:51:44 +12:00 (Migrated from gitlab.com)

Hi @kitplummer.

This is exactly the sort of project that Wafer was designed to support. Technically you don't need Wafer to enable support, but while writing drivers I found a lot of repeated code which Wafer eliminates.

That said, I haven't written any drivers for SPI devices yet, so Wafer's support for them is just a best guess at this stage. If you find any rough edges then feel free to open an issue for me to take a look.

Good luck with your project!

Hi @kitplummer. This is exactly the sort of project that Wafer was designed to support. Technically you don't *need* Wafer to enable support, but while writing drivers I found a lot of repeated code which Wafer eliminates. That said, I haven't written any drivers for SPI devices yet, so Wafer's support for them is just a best guess at this stage. If you find any rough edges then feel free to open an issue for me to take a look. Good luck with your project!
kitplummer commented 2020-05-07 07:56:05 +12:00 (Migrated from gitlab.com)

Thanks. I'm going to start digging, I like the abstraction and could already sense a need for it (which is what lead me to search in the first place). I know I could get by with Circuits.SPI and Circuits.GPIO but the "bit" work had me scratching my head a lot (between Erlang stuff and trying to decipher the other Python driver). Appreciate the docs and other examples you've made available.

Thanks. I'm going to start digging, I like the abstraction and could already sense a need for it (which is what lead me to search in the first place). I know I could get by with Circuits.SPI and Circuits.GPIO but the "bit" work had me scratching my head a lot (between Erlang stuff and trying to decipher the other Python driver). Appreciate the docs and other examples you've made available.
jimsy commented 2020-05-07 07:57:42 +12:00 (Migrated from gitlab.com)

I was just re-reading the docs and thinking that they're a little sparse 😄!

Let me know how you get on with your project.

I was just re-reading the docs and thinking that they're a little sparse :smile:! Let me know how you get on with your project.
kitplummer commented 2020-05-07 08:01:17 +12:00 (Migrated from gitlab.com)

Ha. Ok, here's the deal - in exchange for a bit of support as I get on
with it, I'm going to start with a "blinky" helloworld experiment. Once I
have that, I'll write a simple blog post and link to Wafer and submit a
simple PR with the 'pre-getting started' steps.

Ha. Ok, here's the deal - in exchange for a bit of support as I get on with it, I'm going to start with a "blinky" helloworld experiment. Once I have that, I'll write a simple blog post and link to Wafer and submit a simple PR with the 'pre-getting started' steps.
jimsy commented 2020-05-07 08:02:53 +12:00 (Migrated from gitlab.com)

Works for me!

Works for me!
kitplummer commented 2020-05-08 00:56:13 +12:00 (Migrated from gitlab.com)

@jimsy - sorry to bug already. need a pointer.

** (Protocol.UndefinedError) protocol Wafer.Chip not implemented for %Wafer.Driver.Circuits.SPI{bus: "spidev0.0", ref: #Reference<0.1518123335.710803471.261055>} of type Wafer.Driver.Circuits.SPI (a struct). This protocol is implemented for the following type(s): Rf24l01, Wafer.Driver.ElixirALE.I2C, Wafer.Driver.Circuits.I2C, Wafer.Driver.Fake

I've been using the pca9641 as my guide and know the registers it is accessing are on the I2C driver. Is this a declaration problem, or have I run into the first missing SPI functionality?

@jimsy - sorry to bug already. need a pointer. ```sh ** (Protocol.UndefinedError) protocol Wafer.Chip not implemented for %Wafer.Driver.Circuits.SPI{bus: "spidev0.0", ref: #Reference<0.1518123335.710803471.261055>} of type Wafer.Driver.Circuits.SPI (a struct). This protocol is implemented for the following type(s): Rf24l01, Wafer.Driver.ElixirALE.I2C, Wafer.Driver.Circuits.I2C, Wafer.Driver.Fake ``` I've been using the pca9641 as my guide and know the registers it is accessing are on the I2C driver. Is this a declaration problem, or have I run into the first missing SPI functionality?
kitplummer commented 2020-05-08 05:38:26 +12:00 (Migrated from gitlab.com)

Ah I see now, SPI just has transfer which pretty much always write_read in a single thing in the Circuits.SPI library.

Ah I see now, SPI just has `transfer` which pretty much always write_read in a single thing in the Circuits.SPI library.
jimsy commented 2020-05-08 08:45:56 +12:00 (Migrated from gitlab.com)

That's right. That's because that's just how the SPI protocol works - there's really only one operation which is basically swapping a byte from the host for a byte from the client. I'm not really sure about what the conventions for reading/writing registers are. I'll happily help you implement them though. Can you link me to the datasheet for the device you're working with?

That's right. That's because that's just how the SPI protocol works - there's really only one operation which is basically swapping a byte from the host for a byte from the client. I'm not really sure about what the conventions for reading/writing registers are. I'll happily help you implement them though. Can you link me to the datasheet for the device you're working with?
kitplummer commented 2020-05-08 08:49:49 +12:00 (Migrated from gitlab.com)

https://www.sparkfun.com/datasheets/Components/nRF24L01_prelim_prod_spec_1_2.pdf and here's the Python driver I was learning from too: https://github.com/2bndy5/CircuitPython_nRF24L01/blob/master/circuitpython_nrf24l01/rf24.py

I was able to write and registers via the SPI.transfer() directly in learning some things too.

https://www.sparkfun.com/datasheets/Components/nRF24L01_prelim_prod_spec_1_2.pdf and here's the Python driver I was learning from too: https://github.com/2bndy5/CircuitPython_nRF24L01/blob/master/circuitpython_nrf24l01/rf24.py I was able to write and registers via the `SPI.transfer()` directly in learning some things too.
jimsy commented 2020-05-08 09:01:10 +12:00 (Migrated from gitlab.com)

Cool. I'll take a look over the weekend and see what I can find. Do you have a repo somewhere I can take a look at?

Cool. I'll take a look over the weekend and see what I can find. Do you have a repo somewhere I can take a look at?
kitplummer commented 2020-05-08 11:52:17 +12:00 (Migrated from gitlab.com)

Awesome. Much appreciated.

This is as far as I go before I found wafer: https://gitlab.com/kitplummer/nrf24l01/snippets/1974729
Just pushed up my what I got to this morning: https://gitlab.com/kitplummer/nrf24l01 - not very far.

Awesome. Much appreciated. This is as far as I go before I found wafer: https://gitlab.com/kitplummer/nrf24l01/snippets/1974729 Just pushed up my what I got to this morning: https://gitlab.com/kitplummer/nrf24l01 - not very far.
jimsy commented 2020-05-10 09:02:23 +12:00 (Migrated from gitlab.com)

Okay. So it looks like we need to implement the Wafer.Chip protocol for your Conn. Looking at the datasheet, there's a handy list of instructions:

Screen_Shot_2020-05-10_at_09.01.19

I'll take a swing at it and send you a PR - I don't have the actual hardware to test, but it should at least give you an idea how to go forward.

Okay. So it looks like we need to implement the `Wafer.Chip` protocol for your `Conn`. Looking at the datasheet, there's a handy list of instructions: ![Screen_Shot_2020-05-10_at_09.01.19](/uploads/a3a9cee6403edf188520e2a23a30ff84/Screen_Shot_2020-05-10_at_09.01.19.png) I'll take a swing at it and send you a PR - I don't have the actual hardware to test, but it should at least give you an idea how to go forward.
kitplummer commented 2020-05-10 09:11:18 +12:00 (Migrated from gitlab.com)

Rad, much appreciated. I'd be willing to send a couple radios your way for the effort.

Rad, much appreciated. I'd be willing to send a couple radios your way for the effort.
jimsy commented 2020-05-10 09:22:11 +12:00 (Migrated from gitlab.com)

Okay, so I've sent you a PR to try. Note that the Chip protocol is only interested in reading and writing registers and you're going to have to write your own code to drive the actual data transfers using the other six instructions above.

Okay, so I've sent you a PR to try. Note that the `Chip` protocol is only interested in reading and writing registers and you're going to have to write your own code to drive the actual data transfers using the other six instructions above.
kitplummer commented 2020-05-10 09:55:03 +12:00 (Migrated from gitlab.com)

Merged it, now will see if I can grok this register and bit stuff. :) Thanks again.

Merged it, now will see if I can grok this register and bit stuff. :) Thanks again.
kitplummer commented 2020-05-13 03:14:41 +12:00 (Migrated from gitlab.com)

Heyo. Stumped by something...

Code:

data_rate =
  cond do
    data_rate == 1 -> 0
    data_rate == 2 -> 8
    data_rate == 250 -> 0x20
  end
      
pa_level = (3 - round(pa_level / -6)) * 2
rf_setup = bor(data_rate, pa_level)
IO.inspect <<rf_setup>>, label: "RF_SETUP_PRE"
{:ok, <<_, rf_setup_reg>>, _} = Registers.write_rf_setup(conn, <<rf_setup>>)
IO.inspect <<rf_setup_reg>>, label: "RF_SETUP"

output:

WRITE DATA: <<6>>
WRITE INSTRUCTION: <<38, 6>>
WRITTEN DATA: <<14>>

Perhaps a red-herring but the <<14>> is my "config" data. But I can't for the life of me figure this out.

The Registers for rf_setup is:

  defregister(:rf_setup, 0x06, :rw, 1)

Here's the Chip write_register:

def write_register(%Rf24l01{conn: conn} = device, address, data) do
    instruction = <<1::integer-size(3), address::integer-size(5), data::binary>>
    IO.inspect data, label: "WRITE DATA"
    IO.inspect instruction, label: "WRITE INSTRUCTION"
    case SPI.transfer(conn, instruction) do
      {:ok, <<data, _>>, conn} -> 
        IO.inspect <<data>>, label: "WRITTEN DATA"
        {:ok, <<data>>, %{device | conn: conn}}
      {:error, reason} -> {:error, reason}
    end
  end

Any troubleshooting pointers @jimsy? It appears that any call to write_register only ever returns the same data as <<14>>, which was the first write.

Heyo. Stumped by something... Code: ```elixir data_rate = cond do data_rate == 1 -> 0 data_rate == 2 -> 8 data_rate == 250 -> 0x20 end pa_level = (3 - round(pa_level / -6)) * 2 rf_setup = bor(data_rate, pa_level) IO.inspect <<rf_setup>>, label: "RF_SETUP_PRE" {:ok, <<_, rf_setup_reg>>, _} = Registers.write_rf_setup(conn, <<rf_setup>>) IO.inspect <<rf_setup_reg>>, label: "RF_SETUP" ``` output: ```sh WRITE DATA: <<6>> WRITE INSTRUCTION: <<38, 6>> WRITTEN DATA: <<14>> ``` Perhaps a red-herring but the `<<14>>` is my "config" data. But I can't for the life of me figure this out. The `Registers` for `rf_setup` is: ```elixir defregister(:rf_setup, 0x06, :rw, 1) ``` Here's the Chip `write_register`: ```elixir def write_register(%Rf24l01{conn: conn} = device, address, data) do instruction = <<1::integer-size(3), address::integer-size(5), data::binary>> IO.inspect data, label: "WRITE DATA" IO.inspect instruction, label: "WRITE INSTRUCTION" case SPI.transfer(conn, instruction) do {:ok, <<data, _>>, conn} -> IO.inspect <<data>>, label: "WRITTEN DATA" {:ok, <<data>>, %{device | conn: conn}} {:error, reason} -> {:error, reason} end end ``` Any troubleshooting pointers @jimsy? It appears that any call to `write_register` only ever returns the same data as `<<14>>`, which was the first write.
jimsy commented 2020-05-13 08:46:35 +12:00 (Migrated from gitlab.com)

Remember that an SPI transfer is a "swap". You should discard the results of the write register instruction - in this case I believe you're getting the old register contents, but I could be wrong.

In this case if you want to verify what was written to the register then you should immediately follow it with a read register instruction.

SparkFun has a good description of how SPI works.

Remember that an SPI transfer is a "swap". You should discard the results of the write register instruction - in this case I believe you're getting the old register contents, but I could be wrong. In this case if you want to verify what was written to the register then you should immediately follow it with a read register instruction. [SparkFun has a good description of how SPI works](https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all#a-synchronous-solution).
kitplummer commented 2020-05-13 10:17:42 +12:00 (Migrated from gitlab.com)

I've thought about that, and that's where I started, but have been scrambling to figure out why it appears the write isn't happening. It is the same output when I follow the write of <<6>>, the subsequent read is <<14>> all the time, for each register. Will keep poking. Thanks for the link.

I've thought about that, and that's where I started, but have been scrambling to figure out why it appears the write isn't happening. It is the same output when I follow the write of <<6>>, the subsequent read is <<14>> all the time, for each register. Will keep poking. Thanks for the link.
kitplummer commented 2020-05-13 10:31:32 +12:00 (Migrated from gitlab.com)

I'm an idiot. Was looking at the wrong byte that is returned with read_register. Damn.

I'm an idiot. Was looking at the wrong byte that is returned with `read_register`. Damn.
jimsy commented 2020-05-13 11:28:00 +12:00 (Migrated from gitlab.com)

You're not an idiot. You just made a mistake. We all do it.

You're not an idiot. You just made a mistake. We all do it.
jimsy commented 2020-05-13 11:33:05 +12:00 (Migrated from gitlab.com)

Which makes me realise that problem is one of my creation.

The read_register and swap_register implementations should probably drop the first byte of data in the response, since it's the instruction byte.

Which makes me realise that problem is one of my creation. The `read_register` and `swap_register` implementations should probably drop the first byte of data in the response, since it's the instruction byte.
kitplummer commented 2020-05-13 11:45:46 +12:00 (Migrated from gitlab.com)

I'd been paying attention to that as I was reading the code and docs...so I
knew what it was. Continuously improving...

I'd been paying attention to that as I was reading the code and docs...so I knew what it was. Continuously improving...
kitplummer commented 2020-05-14 11:11:29 +12:00 (Migrated from gitlab.com)

Hey @jimsy - probably a simple question. I need to access the Wafer.Chip.impl.read_register directly from my driver, in order to do a read with a dynamic number of bytes (thinking that eliminates the defregister macro).

If I call it with the conn I'm using for accessing the registers like this:

result = Wafer.Chip.Rf24l01.read_register(conn, 0x61, curr_pl_size)

I get:

** (Protocol.UndefinedError) protocol Wafer.Chip not implemented for true of type Atom. This protocol is implemented for the following type(s): Rf24l01, Wafer.Driver.ElixirALE.I2C, Wafer.Driver.Circuits.I2C, Wafer.Driver.Fake

If I call it this way:

result = Wafer.Chip.Rf24l01.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size)

I get:

** (Protocol.UndefinedError) protocol Wafer.SPI not implemented for %Rf24l01{ce_pin: %Wafer.Driver.Circuits.GPIO{direction: :out, pin: 17, ref: #Reference<0.611978235.1876557837.112711>}, conn: %Wafer.Driver.Circuits.SPI{bus: "spidev0.0", ref: #Reference<0.611978235.1876557837.112716>}, csn_pin: %Wafer.Driver.Circuits.GPIO{direction: :out, pin: 25, ref: #Reference<0.611978235.1876557837.112712>}, state: :acquired} of type Rf24l01 (a struct). This protocol is implemented for the following type(s): Wafer.Driver.Circuits.SPI, Wafer.Driver.Fake, Wafer.Driver.ElixirALE.SPI

Am I wrong to think I can access the Chip implementation?

Help!?

Hey @jimsy - probably a simple question. I need to access the Wafer.Chip._impl_.read_register directly from my driver, in order to do a read with a dynamic number of bytes (thinking that eliminates the `defregister` macro). If I call it with the `conn` I'm using for accessing the registers like this: ```elixir result = Wafer.Chip.Rf24l01.read_register(conn, 0x61, curr_pl_size) ``` I get: ```sh ** (Protocol.UndefinedError) protocol Wafer.Chip not implemented for true of type Atom. This protocol is implemented for the following type(s): Rf24l01, Wafer.Driver.ElixirALE.I2C, Wafer.Driver.Circuits.I2C, Wafer.Driver.Fake ``` If I call it this way: ```elixir result = Wafer.Chip.Rf24l01.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size) ``` I get: ```sh ** (Protocol.UndefinedError) protocol Wafer.SPI not implemented for %Rf24l01{ce_pin: %Wafer.Driver.Circuits.GPIO{direction: :out, pin: 17, ref: #Reference<0.611978235.1876557837.112711>}, conn: %Wafer.Driver.Circuits.SPI{bus: "spidev0.0", ref: #Reference<0.611978235.1876557837.112716>}, csn_pin: %Wafer.Driver.Circuits.GPIO{direction: :out, pin: 25, ref: #Reference<0.611978235.1876557837.112712>}, state: :acquired} of type Rf24l01 (a struct). This protocol is implemented for the following type(s): Wafer.Driver.Circuits.SPI, Wafer.Driver.Fake, Wafer.Driver.ElixirALE.SPI ``` Am I wrong to think I can access the Chip implementation? Help!?
jimsy commented 2020-05-14 11:13:47 +12:00 (Migrated from gitlab.com)

Remember that Chip is a protocol, so you should just be able to call Wafer.Chip.read_register(conn, 0x61, curr_pl_size). We implemented it for the Rf24l01 type, so it should just work.

Remember that `Chip` is a protocol, so you should just be able to call `Wafer.Chip.read_register(conn, 0x61, curr_pl_size)`. We implemented it for the `Rf24l01` type, so it should just work.
kitplummer commented 2020-05-14 11:19:45 +12:00 (Migrated from gitlab.com)

I thought so too, but the same Protocol.UndefinedError if I call Wafer.Chip.read_register() instead of Wafer.Chip.Rf24l01.read_register()..

I thought so too, but the same `Protocol.UndefinedError` if I call `Wafer.Chip.read_register()` instead of `Wafer.Chip.Rf24l01.read_register()`..
jimsy commented 2020-05-14 11:21:03 +12:00 (Migrated from gitlab.com)

The way to call it should definitely be: result = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size) Make sure that you derive the SPI protocol for your Conn type.

The way to call it should definitely be: `result = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size)` Make sure that you derive the `SPI` protocol for your Conn type.
kitplummer commented 2020-05-14 11:32:13 +12:00 (Migrated from gitlab.com)

Yep. https://gitlab.com/kitplummer/nrf24l01/-/blob/config/lib/rf24l01.ex#L2

I believe that's happening, here's my sketch/test:

test "greets the world" do
    {:ok, ce_pin_17} = GPIO.acquire(pin: 17, direction: :out)    
    {:ok, csn_pin_25} = GPIO.acquire(pin: 25, direction: :out)
    {:ok, spi} = SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0")
    {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25)
    Rf24l01.init(conn)
    address = <<0xF0F0F0F0D2>>
    IO.inspect address, label: "RX Address"
    Rf24l01.open_rx_pipe(conn, 0, address)
    Rf24l01.start_listening(conn)

    if Rf24l01.any(conn) do
      IO.puts "there be data"
      data = Rf24l01.recv(conn)
      IO.inspect data, "DATA!"
    end

    #assert conn == :ok 
end
Yep. https://gitlab.com/kitplummer/nrf24l01/-/blob/config/lib/rf24l01.ex#L2 I believe that's happening, here's my sketch/test: ```elixir test "greets the world" do {:ok, ce_pin_17} = GPIO.acquire(pin: 17, direction: :out) {:ok, csn_pin_25} = GPIO.acquire(pin: 25, direction: :out) {:ok, spi} = SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0") {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25) Rf24l01.init(conn) address = <<0xF0F0F0F0D2>> IO.inspect address, label: "RX Address" Rf24l01.open_rx_pipe(conn, 0, address) Rf24l01.start_listening(conn) if Rf24l01.any(conn) do IO.puts "there be data" data = Rf24l01.recv(conn) IO.inspect data, "DATA!" end #assert conn == :ok end ```
jimsy commented 2020-05-14 11:40:18 +12:00 (Migrated from gitlab.com)

I had a look over the Chip implementation in your project (I know I wrote it - but I couldn't remember), and it looks like it uses the SPI conn directly anyway, so calling Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size) where conn is the result of the SPI.acquire/1 should work. Can you cut your example down to simply reading the contents of a register and verify that it works?

I had a look over the `Chip` implementation in your project (I know I wrote it - but I couldn't remember), and it looks like it uses the SPI conn directly anyway, so calling `Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size)` where `conn` is the result of the `SPI.acquire/1` should work. Can you cut your example down to simply reading the contents of a register and verify that it works?
jimsy commented 2020-05-14 11:46:04 +12:00 (Migrated from gitlab.com)

ie:

test "it can read a register" do
  {:ok, ce_pin_17} = Wafer.GPIO.acquire(pin: 17, direction: :out)    
  {:ok, csn_pin_25} = Wafer.GPIO.acquire(pin: 25, direction: :out)
  {:ok, spi} = Wafer.SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0")
  {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25)
  assert {:ok, _data, _conn} = Wafer.Chip.read_register(conn, 0, 1)
end
ie: ```elixir test "it can read a register" do {:ok, ce_pin_17} = Wafer.GPIO.acquire(pin: 17, direction: :out) {:ok, csn_pin_25} = Wafer.GPIO.acquire(pin: 25, direction: :out) {:ok, spi} = Wafer.SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0") {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25) assert {:ok, _data, _conn} = Wafer.Chip.read_register(conn, 0, 1) end ```
kitplummer commented 2020-05-14 11:46:51 +12:00 (Migrated from gitlab.com)

Yep, just did that:

 test "greets the world" do
    {:ok, ce_pin_17} = GPIO.acquire(pin: 17, direction: :out)    
    {:ok, csn_pin_25} = GPIO.acquire(pin: 25, direction: :out)
    {:ok, spi} = SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0")
    {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25)

    Rf24l01.init(conn)
    {:ok, <<instruction, data>>, conn} = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x00, 1)
    assert <<14>> == <<data>>

works. Hrm.

Yep, just did that: ```elixir test "greets the world" do {:ok, ce_pin_17} = GPIO.acquire(pin: 17, direction: :out) {:ok, csn_pin_25} = GPIO.acquire(pin: 25, direction: :out) {:ok, spi} = SPI.acquire(speed_hz: 8000000, bus_name: "spidev0.0") {:ok, conn} = Rf24l01.acquire(conn: spi, ce_pin: ce_pin_17, csn_pin: csn_pin_25) Rf24l01.init(conn) {:ok, <<instruction, data>>, conn} = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x00, 1) assert <<14>> == <<data>> ``` works. Hrm.
jimsy commented 2020-05-14 11:47:32 +12:00 (Migrated from gitlab.com)

Okay, so it's working then?

Okay, so it's working then?
kitplummer commented 2020-05-14 11:48:24 +12:00 (Migrated from gitlab.com)

Need to work backwards and figure out what is blowing up the function now.

Need to work backwards and figure out what is blowing up the function now.
jimsy commented 2020-05-14 11:49:52 +12:00 (Migrated from gitlab.com)

Okay. I suggest you also fix your Chip impl so that read_register looks like this:

  def read_register(%Rf24l01{conn: conn} = device, address, bytes) do
    payload_bytes = bytes * 8
    instruction = <<0::integer-size(3), address::integer-size(5), 0::integer-size(payload_bytes)>>
    case SPI.transfer(conn, instruction) do
      {:ok, <<_, data::binary>>, conn} -> 
        {:ok, data, %{device | conn: conn}}
      {:error, reason} -> {:error, reason}
    end
  end

Hopefully helps with your sanity so that you don't have to drop the instruction byte every time you access a register.

Okay. I suggest you also fix your Chip impl so that read_register looks like this: ```elixir def read_register(%Rf24l01{conn: conn} = device, address, bytes) do payload_bytes = bytes * 8 instruction = <<0::integer-size(3), address::integer-size(5), 0::integer-size(payload_bytes)>> case SPI.transfer(conn, instruction) do {:ok, <<_, data::binary>>, conn} -> {:ok, data, %{device | conn: conn}} {:error, reason} -> {:error, reason} end end ``` Hopefully helps with your sanity so that you don't have to drop the instruction byte every time you access a register.
kitplummer commented 2020-05-14 11:50:20 +12:00 (Migrated from gitlab.com)

Wilco. Thanks!

Wilco. Thanks!
jimsy commented 2020-05-20 07:28:23 +12:00 (Migrated from gitlab.com)

@kitplummer how are you getting on?

@kitplummer how are you getting on?
kitplummer commented 2020-05-20 08:01:35 +12:00 (Migrated from gitlab.com)

Oh, slow. Actually had my free time re-prioritized a little bit. Have
been able to RX on the radio, so think I'm good on the wafer front. Now
it's a matter of implementing the rest of functionality needed, cleaning
things up, and push it out there. I'll get there. Thanks for checking in,
super appreciated.

Oh, slow. Actually had my free time re-prioritized a little bit. Have been able to RX on the radio, so think I'm good on the `wafer` front. Now it's a matter of implementing the rest of functionality needed, cleaning things up, and push it out there. I'll get there. Thanks for checking in, super appreciated.
kitplummer commented 2020-06-03 02:58:34 +12:00 (Migrated from gitlab.com)

Pretty stuck now, have debugged about as best as I can to make sure the config/initialization registers are good. But whenever I go to read received data I only ever get: ???????????????

Completely baffled. Any generic ideas?

Pretty stuck now, have debugged about as best as I can to make sure the config/initialization registers are good. But whenever I go to read received data I only ever get: `???????????????` Completely baffled. Any generic ideas?
kitplummer commented 2020-06-03 03:41:13 +12:00 (Migrated from gitlab.com)

Actually, I think it is the "address" I am trying to use. I need to get 0xF0F0F0F0D2 as a bytearray.

Actually, I think it is the "address" I am trying to use. I need to get `0xF0F0F0F0D2` as a bytearray.
kitplummer commented 2020-06-04 03:55:01 +12:00 (Migrated from gitlab.com)

Hrm...this is hard. :D Sorry for using this issue as a mental/historical reference. Currently trying to debug through all of the radio config to figure out why the actual read of the payload register isn't working. Since flush_rx is write only, I'm left to guess if it is actually working...

Hrm...this is hard. :D Sorry for using this issue as a mental/historical reference. Currently trying to debug through all of the radio config to figure out why the actual read of the payload register isn't working. Since flush_rx is write only, I'm left to guess if it is actually working...
kitplummer commented 2020-06-05 04:57:14 +12:00 (Migrated from gitlab.com)

@jimsy - ok, i need to access the read_register function that I've got in the defimpl Wafer.Chip, for Rf24l01 from my Rf24l01 module. How should I be doing that?

Like this:

{:ok, result, conn} = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size)

Or some other way?

When I do the above I get ??????????? or some series of the question marks no matter what. All the register stuff up to this works fine, can verify my writes with subsequent reads. The curr_pl_size is a read on a register to know how much data is in the receive buffer at that 0x61 address.

Any ideas?

@jimsy - ok, i need to access the `read_register` function that I've got in the `defimpl Wafer.Chip, for Rf24l01` from my `Rf24l01` module. How should I be doing that? Like this: ``` {:ok, result, conn} = Wafer.Chip.read_register(%Rf24l01{conn: conn}, 0x61, curr_pl_size) ``` Or some other way? When I do the above I get `???????????` or some series of the question marks no matter what. All the register stuff up to this works fine, can verify my writes with subsequent reads. The `curr_pl_size` is a read on a register to know how much data is in the receive buffer at that `0x61` address. Any ideas?
jimsy commented 2020-06-24 13:41:34 +12:00 (Migrated from gitlab.com)

Hi @kitplummer - sorry I've taken so long to respond - there's been a lot going on here for the last while. To access the protocol implementation you just need to call the protocol with the correct type of data - which it looks like you're doing. Are you still stuck?

Hi @kitplummer - sorry I've taken so long to respond - there's been a lot going on here for the last while. To access the protocol implementation you just need to call the protocol with the correct type of data - which it looks like you're doing. Are you still stuck?
jimsy commented 2020-08-25 08:24:52 +12:00 (Migrated from gitlab.com)

@kitplummer how are you getting on?

@kitplummer how are you getting on?
kitplummer commented 2020-08-25 09:08:34 +12:00 (Migrated from gitlab.com)

Heyo. Stopped in my tracks. Have had to reprioritize to a few other
things. Thanks for checkin' in. Feel free to close this out if you want.

Heyo. Stopped in my tracks. Have had to reprioritize to a few other things. Thanks for checkin' in. Feel free to close this out if you want.
james closed this issue 2023-11-24 20:24:07 +13:00
Sign in to join this conversation.
No labels
renovate
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: james/wafer#1
No description provided.