rust-iot / rust-radio-sx128x

Rust driver for the Semtec SX128x series of 2.4GHz LoRa/ISM radio transceivers
Mozilla Public License 2.0
13 stars 6 forks source link

Minimal embedded example? #118

Open har7an opened 2 years ago

har7an commented 2 years ago

Hello,

first up: It's nice to see that someone has already undergone the effort to write a rust crate for the SX128x chips, so thank you very much for that!

I'm trying to hack up a custom firmware for some RC modems (In particular: HappyModel ES24TX Pro) in Rust. Unfortunately the crates documentation on its own doesn't give me enough of an idea what exactly the different Pins are that I need. In particular I assume that since Sx128x takes a cs pin, I mustn't register that one with the SPI Interface, right?

Furthermore I do have a busy pin, but I have no idea what to do about ready and sdn. Could you elaborate on what these do, or maybe share an example that contains a coarse schematic so I can understand what this means?

Thank you in advance!

har7an commented 2 years ago

Reading through the code it seems to me that ready is the DIO lane for the interrupts and sdn is used solely for resetting the modem. Is that correct?

ryankurte commented 2 years ago

howdy! it would definitely be good to have a nice example / demo with pictures that folks could pick up huh.

sorry for the low image quality but, an example on a RPI:

image

with the pin configuration:

export SPI_DEV=/dev/spidev0.0
export SPI_BAUD=2000000
export CS_PIN=23 
export RESET_PIN=16
export BUSY_PIN=18
export READY_PIN=20
har7an commented 2 years ago

Thanks for the quick reply!

  • CS goes with the SPI interface yes

I see. Unfortunately the HAL for my uC (ESP32) has hardware-controlled CS lines and actually won't let me create SPI interfaces without specifying the CS line. Now Sx128x::spi wants to have their own CS line, too. So I guess that is best solved by giving either of these some dummy IO to play with, right? Would it hurt your API if the CS line didn't do anything? Or is CS relevant for controlling the radio state beyond starting SPI communication?

Also I don't understand what exactly SpiBase does. The first argument to Sx128x::spi expects something that has SpiBase implemented, but how would I do that? Based on the errors I see when compiling it expects something that implements embedded_hal::spi::blocking::{Transactional, Transfer, Write}. My HAL is using embedded-hal 1.0.0-alpha.8 instead of alpha.7, I guess that explains the incompatibility?

ryankurte commented 2 years ago

Unfortunately the HAL for my uC (ESP32) has hardware-controlled CS lines

often as not the CS behaviour of the uC is not quite adequate for driving peripherals, in this instance you'd disable the SPI peripheral CS and just use another GPIO pin (we're working on API improvements for this in embedded-hal, just, not quite there yet).

Also I don't understand what exactly SpiBase does

SpiBase is basically a trait alias to simplify the rest of the code (and towards supporting UART comms, though i never ended up needing it).

My HAL is using embedded-hal 1.0.0-alpha.8 instead of alpha.7, I guess that explains the incompatibility?

that would be it, yep

har7an commented 2 years ago

often as not the CS behaviour of the uC is not quite adequate for driving peripherals,

I understand, thank you for clarifying. Does that mean you are an embedded-hal developer? If so, would you mind if I ask you some SPI-related questions in the near future?

SpiBase is basically a trait alias to simplify the rest of the code

That makes sense.

Since my uC forces me to use ehal alpha.8, I'll try to get the SpiBus trait implemented there and will probably end up forking radio-sx128x to implement the same API here, too. Would you accept a PR in case I manage to finish this work?

har7an commented 2 years ago

I managed to hack this crate and my HAL so both implement the SPI traits from embedded-hal 1.0.0-alpha.8. I now have a bit of working code that is at least capable of reading out the firmware version of the modem.

What exactly do I have to do now to enable data transmission via say FLRC? Simply calling start_receive()/check_receive()/get_received() and start/check_transmit() doesn't seem to do have the desired effect. Need I assemble the FLRC frames myself or configure the modems first via the HAL functions?

ryankurte commented 2 years ago

howdy, the radio configurations are a bit cursed in that some features work with different modulations and, well, some don't (#4, #37), so you have to get them right... (probably the config objects could be improved to avoid this)

noting that you need to poll check_receive and check_transmit to advance the operation that's all you should need to do!

the configuration in the utility should show you how to configure the device, and FLRC definitely works when setup correctly. one day i should really get the integration tests back up and running for this...

If so, would you mind if I ask you some SPI-related questions in the near future?

sure, i am happy to help if i can! though please bear in mind i have limited time to spend on a seemingly unlimited list of tasks 🤣

Since my uC forces me to use ehal alpha.8, I'll try to get the SpiBus trait implemented there and will probably end up forking radio-sx128x to implement the same API here, too. Would you accept a PR in case I manage to finish this work?

absolutely, also please feel free to bump any issues / PRs if you need my attention... my github inbox is some 500 issues long