From 327d3cf0df7a1b116ea7ec44d36a569e6ba6ca16 Mon Sep 17 00:00:00 2001 From: ceekdee Date: Mon, 10 Oct 2022 12:35:42 -0500 Subject: [PATCH] Change rak4631 feature to sx126x, removing use in board-specific processing; simplify the P2P examples; correct RSSI computation. --- embassy-lora/Cargo.toml | 4 +- embassy-lora/src/lib.rs | 2 +- .../src/sx126x/sx126x_lora/board_specific.rs | 28 ++----- .../src/sx126x/sx126x_lora/subroutine.rs | 6 +- examples/nrf/Cargo.toml | 2 +- examples/nrf/src/bin/lora_p2p_report.rs | 62 +++++++------- examples/nrf/src/bin/lora_p2p_sense.rs | 84 ++++--------------- 7 files changed, 61 insertions(+), 127 deletions(-) diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index bcb837d9..ea2c3fe6 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -9,7 +9,7 @@ src_base = "https://github.com/embassy-rs/embassy/blob/embassy-lora-v$VERSION/em src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-lora/src/" features = ["time", "defmt"] flavors = [ - { name = "rak4631", target = "thumbv7em-none-eabihf", features = ["rak4631"] }, + { name = "sx126x", target = "thumbv7em-none-eabihf", features = ["sx126x"] }, { name = "sx127x", target = "thumbv7em-none-eabihf", features = ["sx127x", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any"] }, { name = "stm32wl", target = "thumbv7em-none-eabihf", features = ["stm32wl", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any"] }, ] @@ -17,7 +17,7 @@ flavors = [ [lib] [features] -rak4631 = [] +sx126x = [] sx127x = [] stm32wl = ["embassy-stm32", "embassy-stm32/subghz"] time = [] diff --git a/embassy-lora/src/lib.rs b/embassy-lora/src/lib.rs index 342f66b2..3e474843 100644 --- a/embassy-lora/src/lib.rs +++ b/embassy-lora/src/lib.rs @@ -7,7 +7,7 @@ pub(crate) mod fmt; #[cfg(feature = "stm32wl")] pub mod stm32wl; -#[cfg(feature = "rak4631")] +#[cfg(feature = "sx126x")] pub mod sx126x; #[cfg(feature = "sx127x")] pub mod sx127x; diff --git a/embassy-lora/src/sx126x/sx126x_lora/board_specific.rs b/embassy-lora/src/sx126x/sx126x_lora/board_specific.rs index 1fb08588..a7b9e148 100644 --- a/embassy-lora/src/sx126x/sx126x_lora/board_specific.rs +++ b/embassy-lora/src/sx126x/sx126x_lora/board_specific.rs @@ -10,8 +10,7 @@ use super::LoRa; // Defines the time required for the TCXO to wakeup [ms]. const BRD_TCXO_WAKEUP_TIME: u32 = 10; -// Provides board-specific functionality for Semtech SX126x-based boards. Use #[cfg(feature = "board_type")] to specify unique board functionality. -// The base implementation supports the RAK4631 board. +// Provides board-specific functionality for Semtech SX126x-based boards. impl LoRa where @@ -203,44 +202,33 @@ where // Get the radio type pub(super) fn brd_get_radio_type(&mut self) -> RadioType { - #[cfg(feature = "rak4631")] RadioType::SX1262 } // Quiesce the antenna(s). pub(super) fn brd_ant_sleep(&mut self) -> Result<(), RadioError> { - #[cfg(feature = "rak4631")] - { - self.antenna_tx.set_low().map_err(|_| AntTx)?; - self.antenna_rx.set_low().map_err(|_| AntRx)?; - } + self.antenna_tx.set_low().map_err(|_| AntTx)?; + self.antenna_rx.set_low().map_err(|_| AntRx)?; Ok(()) } // Prepare the antenna(s) for a receive operation pub(super) fn brd_ant_set_rx(&mut self) -> Result<(), RadioError> { - #[cfg(feature = "rak4631")] - { - self.antenna_tx.set_low().map_err(|_| AntTx)?; - self.antenna_rx.set_high().map_err(|_| AntRx)?; - } + self.antenna_tx.set_low().map_err(|_| AntTx)?; + self.antenna_rx.set_high().map_err(|_| AntRx)?; Ok(()) } // Prepare the antenna(s) for a send operation pub(super) fn brd_ant_set_tx(&mut self) -> Result<(), RadioError> { - #[cfg(feature = "rak4631")] - { - self.antenna_rx.set_low().map_err(|_| AntRx)?; - self.antenna_tx.set_high().map_err(|_| AntTx)?; - } + self.antenna_rx.set_low().map_err(|_| AntRx)?; + self.antenna_tx.set_high().map_err(|_| AntTx)?; Ok(()) } // Check if the given RF frequency is supported by the hardware pub(super) async fn brd_check_rf_frequency(&mut self, _frequency: u32) -> Result> { - #[cfg(feature = "rak4631")] - Ok(true) // all frequencies currently supported for the SX1262 within a rak4631 + Ok(true) } // Get the duration required for the TCXO to wakeup [ms]. diff --git a/embassy-lora/src/sx126x/sx126x_lora/subroutine.rs b/embassy-lora/src/sx126x/sx126x_lora/subroutine.rs index 283e6099..2e78b919 100644 --- a/embassy-lora/src/sx126x/sx126x_lora/subroutine.rs +++ b/embassy-lora/src/sx126x/sx126x_lora/subroutine.rs @@ -564,7 +564,7 @@ where pub(super) async fn sub_get_rssi_inst(&mut self) -> Result> { let mut buffer = [0x00u8]; self.brd_read_command(OpCode::GetRSSIInst, &mut buffer).await?; - let rssi: i8 = (-(buffer[0] as i8)) >> 1; // check this ??? + let rssi: i8 = ((-(buffer[0] as i32)) >> 1) as i8; // check this ??? Ok(rssi) } @@ -597,9 +597,9 @@ where self.brd_read_command(OpCode::GetPacketStatus, &mut status).await?; // check this ??? - let rssi = (-(status[0] as i8)) >> 1; + let rssi = ((-(status[0] as i32)) >> 1) as i8; let snr = ((status[1] as i8) + 2) >> 2; - let signal_rssi = (-(status[2] as i8)) >> 1; + let signal_rssi = ((-(status[2] as i32)) >> 1) as i8; let freq_error = self.frequency_error; Ok(PacketStatus { diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index 91c41821..6949042e 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -18,7 +18,7 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defm embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true } embedded-io = "0.3.0" -embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["rak4631", "time", "defmt"], optional = true } +embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true } lorawan-device = { version = "0.8.0", default-features = false, features = ["async"], optional = true } lorawan = { version = "0.7.1", default-features = false, features = ["default-crypto"], optional = true } diff --git a/examples/nrf/src/bin/lora_p2p_report.rs b/examples/nrf/src/bin/lora_p2p_report.rs index 4ba3d30c..d512b83f 100644 --- a/examples/nrf/src/bin/lora_p2p_report.rs +++ b/examples/nrf/src/bin/lora_p2p_report.rs @@ -1,4 +1,6 @@ //! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +//! Other nrf/sx126x combinations may work with appropriate pin modifications. +//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_sense.rs. #![no_std] #![no_main] #![macro_use] @@ -18,7 +20,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); let mut spi_config = spim::Config::default(); - spi_config.frequency = spim::Frequency::M1; // M16 ??? + spi_config.frequency = spim::Frequency::M16; let mut radio = { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); @@ -47,38 +49,30 @@ async fn main(_spawner: Spawner) { Timer::after(Duration::from_secs(5)).await; start_indicator.set_low(); - match radio.lora.sleep().await { - Ok(()) => info!("Sleep successful"), - Err(err) => info!("Sleep unsuccessful = {}", err), + loop { + let rf_config = RfConfig { + frequency: 903900000, // channel in Hz + bandwidth: Bandwidth::_250KHz, + spreading_factor: SpreadingFactor::_10, + coding_rate: CodingRate::_4_8, + }; + + let mut buffer = [00u8; 100]; + + // P2P receive + match radio.rx(rf_config, &mut buffer).await { + Ok((buffer_len, rx_quality)) => info!( + "RX received = {:?} with length = {} rssi = {} snr = {}", + &buffer[0..buffer_len], + buffer_len, + rx_quality.rssi(), + rx_quality.snr() + ), + Err(err) => info!("RX error = {}", err), + } + + debug_indicator.set_high(); + Timer::after(Duration::from_secs(2)).await; + debug_indicator.set_low(); } - - let rf_config = RfConfig { - frequency: 903900000, // channel in Hz - bandwidth: Bandwidth::_250KHz, - spreading_factor: SpreadingFactor::_10, - coding_rate: CodingRate::_4_8, - }; - - let mut buffer = [00u8; 100]; - - // P2P receive - match radio.rx(rf_config, &mut buffer).await { - Ok((buffer_len, rx_quality)) => info!( - "RX received = {:?} with length = {} rssi = {} snr = {}", - &buffer[0..buffer_len], - buffer_len, - rx_quality.rssi(), - rx_quality.snr() - ), - Err(err) => info!("RX error = {}", err), - } - - match radio.lora.sleep().await { - Ok(()) => info!("Sleep successful"), - Err(err) => info!("Sleep unsuccessful = {}", err), - } - - debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; - debug_indicator.set_low(); } diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs index 405a8403..b9768874 100644 --- a/examples/nrf/src/bin/lora_p2p_sense.rs +++ b/examples/nrf/src/bin/lora_p2p_sense.rs @@ -1,4 +1,6 @@ //! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +//! Other nrf/sx126x combinations may work with appropriate pin modifications. +//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_report.rs. #![no_std] #![no_main] #![macro_use] @@ -9,8 +11,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_lora::sx126x::*; -use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin as _, Pull}; -use embassy_nrf::temp::Temp; +use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{interrupt, spim}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::pubsub::{PubSubChannel, Publisher}; @@ -18,10 +19,6 @@ use embassy_time::{Duration, Timer}; use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; use {defmt_rtt as _, panic_probe as _, panic_probe as _}; -// Sensor packet constants -const TEMPERATURE_UID: u8 = 0x01; -const MOTION_UID: u8 = 0x02; - // Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) static MESSAGE_BUS: PubSubChannel = PubSubChannel::new(); @@ -32,53 +29,20 @@ enum Message { } #[embassy_executor::task] -async fn temperature_task( - mut temperature: Temp<'static>, - publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, -) { - Timer::after(Duration::from_secs(45)).await; // stabilize for 45 seconds - - let mut temperature_reporting_threshhold = 10; - +async fn temperature_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) { + // Publish a fake temperature every 43 seconds, minimizing LORA traffic. loop { - let value = temperature.read().await; - let mut temperature_val = value.to_num::(); - - info!("Temperature: {}", temperature_val); - - // only report every 2 degree Celsius drops, from 9 through 5, but starting at 3 always report - - if temperature_val == 8 || temperature_val == 6 || temperature_val == 4 { - temperature_val += 1; - } - - if temperature_reporting_threshhold > temperature_val - && (temperature_val == 9 || temperature_val == 7 || temperature_val == 5) - { - temperature_reporting_threshhold = temperature_val; - publisher.publish(Message::Temperature(temperature_val)).await; - } else if temperature_val <= 3 { - publisher.publish(Message::Temperature(temperature_val)).await; - } - - Timer::after(Duration::from_secs(20 * 60)).await; + Timer::after(Duration::from_secs(43)).await; + publisher.publish(Message::Temperature(9)).await; } } #[embassy_executor::task] -async fn motion_detection_task( - mut pir_pin: Input<'static, AnyPin>, - publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, -) { - Timer::after(Duration::from_secs(30)).await; // stabilize for 30 seconds - +async fn motion_detection_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) { + // Publish a fake motion detection every 79 seconds, minimizing LORA traffic. loop { - // wait for motion detection - pir_pin.wait_for_low().await; + Timer::after(Duration::from_secs(79)).await; publisher.publish(Message::MotionDetected).await; - - // wait a minute before setting up for more motion detection - Timer::after(Duration::from_secs(60)).await; } } @@ -91,7 +55,7 @@ async fn main(spawner: Spawner) { let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher()); let mut spi_config = spim::Config::default(); - spi_config.frequency = spim::Frequency::M1; // M16 ??? + spi_config.frequency = spim::Frequency::M16; let mut radio = { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); @@ -113,15 +77,7 @@ async fn main(spawner: Spawner) { } }; - // set up for the temperature task - let temperature_irq = interrupt::take!(TEMP); - let temperature = Temp::new(p.TEMP, temperature_irq); - - // set the motion detection pin - let pir_pin = Input::new(p.P0_10.degrade(), Pull::Up); - let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); - let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard); start_indicator.set_high(); Timer::after(Duration::from_secs(5)).await; @@ -132,15 +88,15 @@ async fn main(spawner: Spawner) { Err(err) => info!("Sleep unsuccessful = {}", err), } - unwrap!(spawner.spawn(temperature_task(temperature, temperature_publisher))); - unwrap!(spawner.spawn(motion_detection_task(pir_pin, motion_detection_publisher))); + unwrap!(spawner.spawn(temperature_task(temperature_publisher))); + unwrap!(spawner.spawn(motion_detection_task(motion_detection_publisher))); loop { let message = lora_tx_subscriber.next_message_pure().await; let tx_config = TxConfig { // 11 byte maximum payload for Bandwidth 125 and SF 10 - pw: 20, // up to 20 // 5 ??? + pw: 10, // up to 20 rf: RfConfig { frequency: 903900000, // channel in Hz, not MHz bandwidth: Bandwidth::_250KHz, @@ -149,13 +105,13 @@ async fn main(spawner: Spawner) { }, }; - let mut buffer = [TEMPERATURE_UID, 0xffu8, MOTION_UID, 0x00u8]; + let mut buffer = [0x00u8]; match message { - Message::Temperature(temperature) => buffer[1] = temperature as u8, - Message::MotionDetected => buffer[3] = 0x01u8, + Message::Temperature(temperature) => buffer[0] = temperature as u8, + Message::MotionDetected => buffer[0] = 0x01u8, }; - // crypto for text ??? + // unencrypted match radio.tx(tx_config, &buffer).await { Ok(ret_val) => info!("TX ret_val = {}", ret_val), Err(err) => info!("TX error = {}", err), @@ -165,9 +121,5 @@ async fn main(spawner: Spawner) { Ok(()) => info!("Sleep successful"), Err(err) => info!("Sleep unsuccessful = {}", err), } - - debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; - debug_indicator.set_low(); } }