embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.63k stars 781 forks source link

LoRaWAN - STM32wl #1894

Open tcpipchip opened 1 year ago

tcpipchip commented 1 year ago

Sir, Where i define the the BAND SUBMASK to me make the JOIN ? I am using the AU915...

ceekdee commented 1 year ago

Presumably you have an 8 channel gateway and wish to prioritize which channel block is used first on join? If so, here is the pertinent PR (not yet merged) in rust-lorawan:

https://github.com/ivajloip/rust-lorawan/pull/110

Otherwise, the current rust-lorawan join operation may take a while to succeed, since it randomly selects an active channel, and many channels are active initially for a fixed channel plan like AU915.

ceekdee commented 1 year ago

Having followed your queries across two different rust LoRaWAN implementations and Embassy, it would be helpful to understand the context for your efforts. My understanding is you are using a LSM110A, which includes an STM32WL LoRa board internally. I am unfamiliar with the LSM110A, but it seems to have an internal LoRaWAN implementation already, and I wonder if it is possible to access the internal STM32WL itself externally. Do you actually need a Rust LoRaWAN/LoRa implementation, or just need to use Rust embedded framework features to access the LoRaWAN API within the LSM110A?

tcpipchip commented 1 year ago

hi, running internally.

I already got success internally with Go, Arduino, SDK STM, zephyr, Mbed, Visuino

now the challenger is RUST :)

tcpipchip commented 1 year ago

Presumably you have an 8 channel gateway and wish to prioritize which channel block is used first on join? If so, here is the pertinent PR (not yet merged) in rust-lorawan:

ivajloip/rust-lorawan#110

Otherwise, the current rust-lorawan join operation may take a while to succeed, since it randomly selects an active channel, and many channels are active initially for a fixed channel plan like AU915.

make sense!

tcpipchip commented 1 year ago

Presumably you have an 8 channel gateway and wish to prioritize which channel block is used first on join? If so, here is the pertinent PR (not yet merged) in rust-lorawan:

ivajloip/rust-lorawan#110

Otherwise, the current rust-lorawan join operation may take a while to succeed, since it randomly selects an active channel, and many channels are active initially for a fixed channel plan like AU915.

about you link, looks that they still implemented the option to define the channels

for example, preferred_channels

ceekdee commented 1 year ago

hi, running internally.

I already got success internally with Go, Arduino, SDK STM, zephyr, Mbed, Visuino

now the challenger is RUST :)

When you say "running internally" in those frameworks, do you mean they are directly controlling the STM32WL, or that they are running the LoRaWAN implementation in the LSM110A, which itself controls the STM32WL?

tcpipchip commented 1 year ago

directly

tcpipchip commented 1 year ago

Presumably you have an 8 channel gateway and wish to prioritize which channel block is used first on join? If so, here is the pertinent PR (not yet merged) in rust-lorawan:

ivajloip/rust-lorawan#110

Otherwise, the current rust-lorawan join operation may take a while to succeed, since it randomly selects an active channel, and many channels are active initially for a fixed channel plan like AU915.

I am not too much familiar with Git

put, how i pull the that update into the EMBASSY ? :)

ceekdee commented 1 year ago

For future reference, what IDE do you use - vscode?

The PR mentioned above is a work in progress and not yet merged into rust-lorawan. There is significant discussion about it. However, if you want to try it in the Embassy stm32wl example lora_lorawan.rs, in your local clone of Embassy:

[patch.crates-io] lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "1323eccc1c470d4259f95f4f315d1be830d572a3"} lorawan = { git = "https://github.com/ivajloip/rust-lorawan", rev = "1ecf8a87261ebcdcb9d33358c60cf951af321081"} lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan", rev = "1ecf8a87261ebcdcb9d33358c60cf951af321081"}

-- change const LORAWAN_REGION to AU915 -- change let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); to: let region: region::Configuration = region::Configuration::new_with_preferred_channels(LORAWAN_REGION, _your_preferredchannels, 5); -- use your end device values: .join(&JoinMode::OTAA { deveui: [0, 0, 0, 0, 0, 0, 0, 0], appeui: [0, 0, 0, 0, 0, 0, 0, 0], appkey: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], }

I have no idea whether the strm32wl setup in the lora_lorawan example will work with your board, but at least that will get you closer to a running example.

ceekdee commented 1 year ago

To run an Embassy example, in your local Embassy clone in the examples/stm32wl directory:

tcpipchip commented 1 year ago

hi @ceekdee i will do this afternoon thanks a lot!!!!!!!

tcpipchip commented 1 year ago

i am back! @ceekdee compiling... on "your_preferred_channels"...how can put directly the values ? I am using channels 8 to 15 in my AU915 gateway :)

ceekdee commented 1 year ago

Try this:

let region: region::Configuration = region::Configuration::new_with_preferred_channels(LORAWAN_REGION, &[0x08], 5).unwrap();

That is, use the first channel in your channel block. Also, add the unwrap() at the end since new_with_preferred_channels returns a Result.

tcpipchip commented 1 year ago

i will try now :)

tcpipchip commented 1 year ago
//! This example runs on a STM32WL board, which has a builtin Semtech Sx1262 radio.
//! It demonstrates LoRaWAN join functionality.
#![no_std]
#![no_main]
#![macro_use]
#![feature(type_alias_impl_trait, async_fn_in_trait)]

use defmt::info;
use embassy_executor::Spawner;
use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_lora::LoraTimer;
use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::rng::{self, Rng};
use embassy_stm32::spi::Spi;
use embassy_stm32::{bind_interrupts, pac, peripherals};
use embassy_time::Delay;
use lora_phy::mod_params::*;
use lora_phy::sx1261_2::SX1261_2;
use lora_phy::LoRa;
use lorawan::default_crypto::DefaultFactory as Crypto;
use lorawan_device::async_device::lora_radio::LoRaRadio;
use lorawan_device::async_device::{region, Device, JoinMode};
use {defmt_rtt as _, panic_probe as _};
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, UartTx};

const LORAWAN_REGION: region::Region = region::Region::AU915; // warning: set this appropriately for the region

bind_interrupts!(struct Irqs{
    SUBGHZ_RADIO => InterruptHandler;
    RNG => rng::InterruptHandler<peripherals::RNG>;
});

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let mut config = embassy_stm32::Config::default();
    config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32;
    config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
    let p = embassy_stm32::init(config);

    pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01));

    let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);

    // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx
    let _ctrl1 = Output::new(p.PB12.degrade(), Level::Low, Speed::High);
    let ctrl2 = Output::new(p.PC13.degrade(), Level::High, Speed::High);
    let _ctrl3 = Output::new(p.PC3.degrade(), Level::High, Speed::High);
    let iv = Stm32wlInterfaceVariant::new(Irqs, None, Some(ctrl2)).unwrap();

    let mut delay = Delay;

    //Configure UART
    let mut usart = UartTx::new(p.USART2, p.PA2, NoDma, Config::default());

     // Transmit Message
     usart.blocking_write("LSM110A RUST\n".as_bytes()).unwrap();

    let lora = {
        match LoRa::new(SX1261_2::new(BoardType::Stm32wlSx1262, spi, iv), true, &mut delay).await {
            Ok(l) => l,
            Err(err) => {
                usart.blocking_write("RADIO ERROR\n".as_bytes()).unwrap();
                info!("Radio error = {}", err);
                return;
            }
        }
    };
    let radio = LoRaRadio::new(lora);
    //let region: region::Configuration = region::Configuration::new(LORAWAN_REGION);
    let region: region::Configuration = region::Configuration::new_with_preferred_channels(LORAWAN_REGION, &[0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f], 5).unwrap();

    let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs));

    defmt::info!("Joining LoRaWAN network");
    usart.blocking_write("Joining LoRaWAN network\n".as_bytes()).unwrap();

    // TODO: Adjust the EUI and Keys according to your network credentials
    match device
        .join(&JoinMode::OTAA {
            deveui: [0x00,0x80,0xe1,0x15,0x05,0x1f,0xce,0xe4],
            appeui: [0, 0, 0, 0, 0, 0, 0, 0],
            appkey: [0x2a, 0xed, 0x51, 0xb8, 0x39, 0xde, 0x8d, 0x83, 0x07, 0x56, 0xb9, 0x7d, 0x2c, 0x03, 0xe8, 0x2d],
        })
        .await
    {
        //Ok(()) => defmt::info!("LoRaWAN network joined"),
        Ok(()) => usart.blocking_write("JOINED LoRaWAN network\n".as_bytes()).unwrap(),
        Err(err) => {
            usart.blocking_write("FAIL JOIN LoRaWAN network\n".as_bytes()).unwrap();
            info!("Radio error = {}", err);
            return;
        }
    };
}

Now, In my case, freeze after try to the join...

a log should be good...

image

ceekdee commented 1 year ago

Is your setup such that you need to use usart instead of collecting debug info at the terminal where you are running the example? This is related to a previous question you asked on Embassy, where the answer indicated using stm32wl's included STLINK and the output from probe-rs run.

tcpipchip commented 1 year ago

my probe-rs run may is not working on my j-link...maybe because i am using the WSL2 ?

today i have to create a hex to burn using the j-flash and j-link

image

image

or maybe i have to use the ST-LINK V2 instead

ceekdee commented 1 year ago

I need to be away for awhile. I would also suggest checking your gateway to see if it saw a join request from your end device. Also, rust-lorawan supports LoRaWAN 1.0.2. If your end device is set up on the network for LoRaWAN 1.0.4, join will probably fail because the dev_nonce is unexpected.

tcpipchip commented 1 year ago

i will order a ST-LINK V2

tcpipchip commented 1 year ago

For future reference, what IDE do you use - vscode?

The PR mentioned above is a work in progress and not yet merged into rust-lorawan. There is significant discussion about it. However, if you want to try it in the Embassy stm32wl example lora_lorawan.rs, in your local clone of Embassy:

  • update examples/stm32wl/Cargo.toml at the end to pull in the GitHub commit associated with the PR:

[patch.crates-io] lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "1323eccc1c470d4259f95f4f315d1be830d572a3"} lorawan = { git = "https://github.com/ivajloip/rust-lorawan", rev = "1ecf8a87261ebcdcb9d33358c60cf951af321081"} lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan", rev = "1ecf8a87261ebcdcb9d33358c60cf951af321081"}

  • in examples/stm32wl/src/bin/lora_lorawan.rs:

-- change const LORAWAN_REGION to AU915 -- change let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); to: let region: region::Configuration = region::Configuration::new_with_preferred_channels(LORAWAN_REGION, _your_preferredchannels, 5); -- use your end device values: .join(&JoinMode::OTAA { deveui: [0, 0, 0, 0, 0, 0, 0, 0], appeui: [0, 0, 0, 0, 0, 0, 0, 0], appkey: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], }

I have no idea whether the strm32wl setup in the lora_lorawan example will work with your board, but at least that will get you closer to a running example.

do you suggest to use vscode ? I am using WSL2

tcpipchip commented 1 year ago

I need to be away for awhile. I would also suggest checking your gateway to see if it saw a join request from your end device. Also, rust-lorawan supports LoRaWAN 1.0.2. If your end device is set up on the network for LoRaWAN 1.0.4, join will probably fail because the dev_nonce is unexpected.

yes, it´s 1.0.2

I will do more tests...thanks!

ceekdee commented 1 year ago

Let's not worry about installing vscode, now that I have a better understanding of your test environment.

tcpipchip commented 1 year ago

i will be back on tests tomorrow.... i will test with a official ST-LINK V2 :)

tcpipchip commented 1 year ago

i finally can burn the STM32WL (LSM110A) with ST LINK V2...

About the LoRaWAN example, modified to LSM110A, still having problems...the TRACE goes freeze in some point...

Still testing...