From 327d3cf0df7a1b116ea7ec44d36a569e6ba6ca16 Mon Sep 17 00:00:00 2001
From: ceekdee <taigatensor@gmail.com>
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 bcb837d9d..ea2c3fe67 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 342f66b2a..3e4748430 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 1fb085887..a7b9e1486 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<SPI, CTRL, WAIT, BUS> LoRa<SPI, CTRL, WAIT>
 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<BUS>> {
-        #[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<BUS>> {
-        #[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<BUS>> {
-        #[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<bool, RadioError<BUS>> {
-        #[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 283e60993..2e78b919b 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<i8, RadioError<BUS>> {
         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 91c418213..6949042e2 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 4ba3d30ce..d512b83f6 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 405a8403f..b9768874b 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<CriticalSectionRawMutex, Message, 2, 1, 2> = 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::<i32>();
-
-        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();
     }
 }