Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions embassy-lora/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ futures = { version = "0.3.17", default-features = false, features = [ "async-aw
embedded-hal = { version = "0.2", features = ["unproven"] }
bit_field = { version = "0.10" }

lorawan-device = { version = "0.8.0", default-features = false, features = ["async"] }
lorawan = { version = "0.7.1", default-features = false }
lorawan-device = { version = "0.9.0", default-features = false, features = ["async"] }
lorawan = { version = "0.7.2", default-features = false }
13 changes: 6 additions & 7 deletions embassy-lora/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![no_std]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait, impl_trait_projections)]
#![allow(incomplete_features)]
//! embassy-lora is a collection of async radio drivers that integrate with the lorawan-device
//! crate's async LoRaWAN MAC implementation.

Expand Down Expand Up @@ -34,13 +35,11 @@ impl lorawan_device::async_device::radio::Timer for LoraTimer {
self.start = Instant::now();
}

type AtFuture<'m> = impl core::future::Future<Output = ()> + 'm;
fn at<'m>(&'m mut self, millis: u64) -> Self::AtFuture<'m> {
Timer::at(self.start + Duration::from_millis(millis))
async fn at(&mut self, millis: u64) {
Timer::at(self.start + Duration::from_millis(millis)).await
}

type DelayFuture<'m> = impl core::future::Future<Output = ()> + 'm;
fn delay_ms<'m>(&'m mut self, millis: u64) -> Self::DelayFuture<'m> {
Timer::after(Duration::from_millis(millis))
async fn delay_ms(&mut self, millis: u64) {
Timer::after(Duration::from_millis(millis)).await
}
}
12 changes: 5 additions & 7 deletions embassy-lora/src/stm32wl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! A radio driver integration for the radio found on STM32WL family devices.
use core::future::{poll_fn, Future};
use core::future::poll_fn;
use core::task::Poll;

use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
Expand Down Expand Up @@ -241,14 +241,12 @@ fn configure_radio(radio: &mut SubGhz<'_, NoDma, NoDma>, config: SubGhzRadioConf
impl<'d, RS: RadioSwitch> PhyRxTx for SubGhzRadio<'d, RS> {
type PhyError = RadioError;

type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm where Self: 'm;
fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> {
async move { self.do_tx(config, buf).await }
async fn tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, Self::PhyError> {
self.do_tx(config, buf).await
}

type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm where Self: 'm;
fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> {
async move { self.do_rx(config, buf).await }
async fn rx(&mut self, config: RfConfig, buf: &mut [u8]) -> Result<(usize, RxQuality), Self::PhyError> {
self.do_rx(config, buf).await
}
}

Expand Down
132 changes: 58 additions & 74 deletions embassy-lora/src/sx126x/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::future::Future;

use defmt::Format;
use embedded_hal::digital::v2::OutputPin;
use embedded_hal_async::digital::Wait;
Expand Down Expand Up @@ -71,83 +69,69 @@ where
{
type PhyError = RadioError<BUS>;

type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm
where
SPI: 'm,
CTRL: 'm,
WAIT: 'm,
BUS: 'm;

fn tx<'m>(&'m mut self, config: TxConfig, buffer: &'m [u8]) -> Self::TxFuture<'m> {
async fn tx(&mut self, config: TxConfig, buffer: &[u8]) -> Result<u32, Self::PhyError> {
trace!("TX START");
async move {
self.lora
.set_tx_config(
config.pw,
config.rf.spreading_factor.into(),
config.rf.bandwidth.into(),
config.rf.coding_rate.into(),
8,
false,
true,
false,
0,
false,
)
.await?;
self.lora.set_max_payload_length(buffer.len() as u8).await?;
self.lora.set_channel(config.rf.frequency).await?;
self.lora.send(buffer, 0xffffff).await?;
self.lora.process_irq(None, None, None).await?;
trace!("TX DONE");
return Ok(0);
}
self.lora
.set_tx_config(
config.pw,
config.rf.spreading_factor.into(),
config.rf.bandwidth.into(),
config.rf.coding_rate.into(),
8,
false,
true,
false,
0,
false,
)
.await?;
self.lora.set_max_payload_length(buffer.len() as u8).await?;
self.lora.set_channel(config.rf.frequency).await?;
self.lora.send(buffer, 0xffffff).await?;
self.lora.process_irq(None, None, None).await?;
trace!("TX DONE");
return Ok(0);
}

type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm
where
SPI: 'm,
CTRL: 'm,
WAIT: 'm,
BUS: 'm;

fn rx<'m>(&'m mut self, config: RfConfig, receiving_buffer: &'m mut [u8]) -> Self::RxFuture<'m> {
async fn rx(
&mut self,
config: RfConfig,
receiving_buffer: &mut [u8],
) -> Result<(usize, RxQuality), Self::PhyError> {
trace!("RX START");
async move {
self.lora
.set_rx_config(
config.spreading_factor.into(),
config.bandwidth.into(),
config.coding_rate.into(),
8,
4,
false,
0u8,
true,
false,
0,
true,
true,
)
.await?;
self.lora.set_max_payload_length(receiving_buffer.len() as u8).await?;
self.lora.set_channel(config.frequency).await?;
self.lora.rx(90 * 1000).await?;
let mut received_len = 0u8;
self.lora
.process_irq(Some(receiving_buffer), Some(&mut received_len), None)
.await?;
trace!("RX DONE");

let packet_status = self.lora.get_latest_packet_status();
let mut rssi = 0i16;
let mut snr = 0i8;
if packet_status.is_some() {
rssi = packet_status.unwrap().rssi as i16;
snr = packet_status.unwrap().snr;
}
self.lora
.set_rx_config(
config.spreading_factor.into(),
config.bandwidth.into(),
config.coding_rate.into(),
8,
4,
false,
0u8,
true,
false,
0,
true,
true,
)
.await?;
self.lora.set_max_payload_length(receiving_buffer.len() as u8).await?;
self.lora.set_channel(config.frequency).await?;
self.lora.rx(90 * 1000).await?;
let mut received_len = 0u8;
self.lora
.process_irq(Some(receiving_buffer), Some(&mut received_len), None)
.await?;
trace!("RX DONE");

Ok((received_len as usize, RxQuality::new(rssi, snr)))
let packet_status = self.lora.get_latest_packet_status();
let mut rssi = 0i16;
let mut snr = 0i8;
if packet_status.is_some() {
rssi = packet_status.unwrap().rssi as i16;
snr = packet_status.unwrap().snr;
}

Ok((received_len as usize, RxQuality::new(rssi, snr)))
}
}
157 changes: 66 additions & 91 deletions embassy-lora/src/sx127x/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::future::Future;

use embedded_hal::digital::v2::OutputPin;
use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::*;
Expand Down Expand Up @@ -88,101 +86,78 @@ where
{
type PhyError = Sx127xError;

type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm
where
SPI: 'm,
CS: 'm,
RESET: 'm,
E: 'm,
I: 'm,
RFS: 'm;

fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> {
async fn tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, Self::PhyError> {
trace!("TX START");
async move {
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
self.rfs.set_tx();
self.radio.set_tx_power(14, 0).await?;
self.radio.set_frequency(config.rf.frequency).await?;
// TODO: Modify radio to support other coding rates
self.radio.set_coding_rate_4(5).await?;
self.radio
.set_signal_bandwidth(bandwidth_to_i64(config.rf.bandwidth))
.await?;
self.radio
.set_spreading_factor(spreading_factor_to_u8(config.rf.spreading_factor))
.await?;

self.radio.set_preamble_length(8).await?;
self.radio.set_lora_pa_ramp().await?;
self.radio.set_lora_sync_word().await?;
self.radio.set_invert_iq(false).await?;
self.radio.set_crc(true).await?;

self.radio.set_dio0_tx_done().await?;

self.radio.transmit_start(buf).await?;

loop {
self.irq.wait_for_rising_edge().await.unwrap();
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
self.rfs.set_tx();
self.radio.set_tx_power(14, 0).await?;
self.radio.set_frequency(config.rf.frequency).await?;
// TODO: Modify radio to support other coding rates
self.radio.set_coding_rate_4(5).await?;
self.radio
.set_signal_bandwidth(bandwidth_to_i64(config.rf.bandwidth))
.await?;
self.radio
.set_spreading_factor(spreading_factor_to_u8(config.rf.spreading_factor))
.await?;

self.radio.set_preamble_length(8).await?;
self.radio.set_lora_pa_ramp().await?;
self.radio.set_lora_sync_word().await?;
self.radio.set_invert_iq(false).await?;
self.radio.set_crc(true).await?;

self.radio.set_dio0_tx_done().await?;

self.radio.transmit_start(buf).await?;

loop {
self.irq.wait_for_rising_edge().await.unwrap();
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
let irq = self.radio.clear_irq().await.ok().unwrap();
if (irq & IRQ::IrqTxDoneMask.addr()) != 0 {
trace!("TX DONE");
return Ok(0);
}
let irq = self.radio.clear_irq().await.ok().unwrap();
if (irq & IRQ::IrqTxDoneMask.addr()) != 0 {
trace!("TX DONE");
return Ok(0);
}
}
}

type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm
where
SPI: 'm,
CS: 'm,
RESET: 'm,
E: 'm,
I: 'm,
RFS: 'm;

fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> {
trace!("RX START");
async move {
self.rfs.set_rx();
self.radio.reset_payload_length().await?;
self.radio.set_frequency(config.frequency).await?;
// TODO: Modify radio to support other coding rates
self.radio.set_coding_rate_4(5).await?;
self.radio
.set_signal_bandwidth(bandwidth_to_i64(config.bandwidth))
.await?;
self.radio
.set_spreading_factor(spreading_factor_to_u8(config.spreading_factor))
.await?;

self.radio.set_preamble_length(8).await?;
self.radio.set_lora_sync_word().await?;
self.radio.set_invert_iq(true).await?;
self.radio.set_crc(true).await?;

self.radio.set_dio0_rx_done().await?;
self.radio.set_mode(RadioMode::RxContinuous).await?;

loop {
self.irq.wait_for_rising_edge().await.unwrap();
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
let irq = self.radio.clear_irq().await.ok().unwrap();
if (irq & IRQ::IrqRxDoneMask.addr()) != 0 {
let rssi = self.radio.get_packet_rssi().await.unwrap_or(0) as i16;
let snr = self.radio.get_packet_snr().await.unwrap_or(0.0) as i8;
let response = if let Ok(size) = self.radio.read_packet_size().await {
self.radio.read_packet(buf).await?;
Ok((size, RxQuality::new(rssi, snr)))
} else {
Ok((0, RxQuality::new(rssi, snr)))
};
trace!("RX DONE");
return response;
}
async fn rx(&mut self, config: RfConfig, buf: &mut [u8]) -> Result<(usize, RxQuality), Self::PhyError> {
self.rfs.set_rx();
self.radio.reset_payload_length().await?;
self.radio.set_frequency(config.frequency).await?;
// TODO: Modify radio to support other coding rates
self.radio.set_coding_rate_4(5).await?;
self.radio
.set_signal_bandwidth(bandwidth_to_i64(config.bandwidth))
.await?;
self.radio
.set_spreading_factor(spreading_factor_to_u8(config.spreading_factor))
.await?;

self.radio.set_preamble_length(8).await?;
self.radio.set_lora_sync_word().await?;
self.radio.set_invert_iq(true).await?;
self.radio.set_crc(true).await?;

self.radio.set_dio0_rx_done().await?;
self.radio.set_mode(RadioMode::RxContinuous).await?;

loop {
self.irq.wait_for_rising_edge().await.unwrap();
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
let irq = self.radio.clear_irq().await.ok().unwrap();
if (irq & IRQ::IrqRxDoneMask.addr()) != 0 {
let rssi = self.radio.get_packet_rssi().await.unwrap_or(0) as i16;
let snr = self.radio.get_packet_snr().await.unwrap_or(0.0) as i8;
let response = if let Ok(size) = self.radio.read_packet_size().await {
self.radio.read_packet(buf).await?;
Ok((size, RxQuality::new(rssi, snr)))
} else {
Ok((0, RxQuality::new(rssi, snr)))
};
trace!("RX DONE");
return response;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/nrf52840/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defm
embedded-io = "0.4.0"
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 }
lorawan-device = { version = "0.9.0", default-features = false, features = ["async"], optional = true }
lorawan = { version = "0.7.2", default-features = false, features = ["default-crypto"], optional = true }

defmt = "0.3"
defmt-rtt = "0.4"
Expand Down
Loading