Skip to content

Commit

Permalink
Changes to match lora-phy #35
Browse files Browse the repository at this point in the history
stm32wl SpiDevice support

Remove return from try block in shared_bus and stm32wl
  • Loading branch information
CBJamo committed Oct 26, 2023
1 parent b6fc682 commit 674a373
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 40 deletions.
15 changes: 7 additions & 8 deletions embassy-embedded-hal/src/shared_bus/asynch/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ where
let mut bus = self.bus.lock().await;
self.cs.set_low().map_err(SpiDeviceError::Cs)?;

let op_res: Result<(), BUS::Error> = try {
let op_res: Result<(), Self::Error> = try {
for op in operations {
match op {
Operation::Read(buf) => bus.read(buf).await?,
Operation::Write(buf) => bus.write(buf).await?,
Operation::Transfer(read, write) => bus.transfer(read, write).await?,
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?,
Operation::Read(buf) => bus.read(buf).await.map_err(SpiDeviceError::Spi)?,
Operation::Write(buf) => bus.write(buf).await.map_err(SpiDeviceError::Spi)?,
Operation::Transfer(read, write) => bus.transfer(read, write).await.map_err(SpiDeviceError::Spi)?,
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await.map_err(SpiDeviceError::Spi)?,
#[cfg(not(feature = "time"))]
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported)?,
#[cfg(feature = "time")]
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
}
Expand All @@ -85,11 +85,10 @@ where
let flush_res = bus.flush().await;
let cs_res = self.cs.set_high();

let op_res = op_res.map_err(SpiDeviceError::Spi)?;
flush_res.map_err(SpiDeviceError::Spi)?;
cs_res.map_err(SpiDeviceError::Cs)?;

Ok(op_res)
op_res
}
}

Expand Down
3 changes: 3 additions & 0 deletions embassy-lora/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ embedded-hal = { version = "0.2", features = ["unproven"] }
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
lora-phy = { version = "2" }
lorawan-device = { version = "0.11.0", default-features = false, features = ["async"], optional = true }

[patch.crates-io]
lora-phy = { git = "https://github.com/CBJamo/lora-phy.git", branch = "SpiDevice" }
26 changes: 0 additions & 26 deletions embassy-lora/src/iv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,6 @@ where
fn set_board_type(&mut self, board_type: BoardType) {
self.board_type = board_type;
}
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
pac::PWR.subghzspicr().modify(|w| w.set_nss(false));
Ok(())
}
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
pac::PWR.subghzspicr().modify(|w| w.set_nss(true));
Ok(())
}
async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> {
pac::RCC.csr().modify(|w| w.set_rfrst(true));
pac::RCC.csr().modify(|w| w.set_rfrst(false));
Expand Down Expand Up @@ -125,7 +117,6 @@ where
/// Base for the InterfaceVariant implementation for an stm32l0/sx1276 combination
pub struct Stm32l0InterfaceVariant<CTRL, WAIT> {
board_type: BoardType,
nss: CTRL,
reset: CTRL,
irq: WAIT,
rf_switch_rx: Option<CTRL>,
Expand All @@ -139,15 +130,13 @@ where
{
/// Create an InterfaceVariant instance for an stm32l0/sx1276 combination
pub fn new(
nss: CTRL,
reset: CTRL,
irq: WAIT,
rf_switch_rx: Option<CTRL>,
rf_switch_tx: Option<CTRL>,
) -> Result<Self, RadioError> {
Ok(Self {
board_type: BoardType::Stm32l0Sx1276, // updated when associated with a specific LoRa board
nss,
reset,
irq,
rf_switch_rx,
Expand All @@ -164,12 +153,6 @@ where
fn set_board_type(&mut self, board_type: BoardType) {
self.board_type = board_type;
}
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
self.nss.set_low().map_err(|_| NSS)
}
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
self.nss.set_high().map_err(|_| NSS)
}
async fn reset(&mut self, delay: &mut impl DelayUs) -> Result<(), RadioError> {
delay.delay_ms(10).await;
self.reset.set_low().map_err(|_| Reset)?;
Expand Down Expand Up @@ -220,7 +203,6 @@ where
/// Base for the InterfaceVariant implementation for a generic Sx126x LoRa board
pub struct GenericSx126xInterfaceVariant<CTRL, WAIT> {
board_type: BoardType,
nss: CTRL,
reset: CTRL,
dio1: WAIT,
busy: WAIT,
Expand All @@ -235,7 +217,6 @@ where
{
/// Create an InterfaceVariant instance for an nrf52840/sx1262 combination
pub fn new(
nss: CTRL,
reset: CTRL,
dio1: WAIT,
busy: WAIT,
Expand All @@ -244,7 +225,6 @@ where
) -> Result<Self, RadioError> {
Ok(Self {
board_type: BoardType::Rak4631Sx1262, // updated when associated with a specific LoRa board
nss,
reset,
dio1,
busy,
Expand All @@ -262,12 +242,6 @@ where
fn set_board_type(&mut self, board_type: BoardType) {
self.board_type = board_type;
}
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
self.nss.set_low().map_err(|_| NSS)
}
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
self.nss.set_high().map_err(|_| NSS)
}
async fn reset(&mut self, delay: &mut impl DelayUs) -> Result<(), RadioError> {
delay.delay_ms(10).await;
self.reset.set_low().map_err(|_| Reset)?;
Expand Down
4 changes: 4 additions & 0 deletions embassy-lora/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#![no_std]
#![feature(async_fn_in_trait)]
#![cfg_attr(feature = "stm32wl", feature(try_blocks))]
//! embassy-lora holds LoRa-specific functionality.
pub(crate) mod fmt;

/// interface variants required by the external lora physical layer crate (lora-phy)
pub mod iv;

#[cfg(feature = "stm32wl")]
pub mod stm32wl;

#[cfg(feature = "time")]
use embassy_time::{Duration, Instant, Timer};

Expand Down
89 changes: 89 additions & 0 deletions embassy-lora/src/stm32wl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use core::fmt::Debug;

use embassy_stm32::peripherals::SUBGHZSPI;
use embassy_stm32::{pac, spi as stm_spi, Peripheral};
use embedded_hal_async::spi::{self, Operation};

pub struct SubGhzSpiDevice<'d, Tx, Rx>
where
Tx: stm_spi::TxDma<SUBGHZSPI>,
Rx: stm_spi::RxDma<SUBGHZSPI>,
{
bus: stm_spi::Spi<'d, SUBGHZSPI, Tx, Rx>,
}

impl<'d, Tx, Rx> SubGhzSpiDevice<'d, Tx, Rx>
where
Tx: stm_spi::TxDma<SUBGHZSPI>,
Rx: stm_spi::RxDma<SUBGHZSPI>,
{
pub fn new(
spi: impl Peripheral<P = SUBGHZSPI> + 'd,
txdma: impl Peripheral<P = Tx> + 'd,
rxdma: impl Peripheral<P = Rx> + 'd,
) -> Self {
let bus = stm_spi::Spi::new_subghz(spi, txdma, rxdma);
Self { bus }
}
}

/// Error returned by SPI device implementations in this crate.
#[derive(Eq, PartialEq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum SpiDeviceError {
/// An operation on the inner SPI bus failed.
Spi(stm_spi::Error),
/// DelayUs operations are not supported when the `time` Cargo feature is not enabled.
DelayUsNotSupported,
}

impl spi::Error for SpiDeviceError {
fn kind(&self) -> spi::ErrorKind {
match self {
Self::Spi(e) => e.kind(),
Self::DelayUsNotSupported => spi::ErrorKind::Other,
}
}
}

impl<Tx, Rx> spi::ErrorType for SubGhzSpiDevice<'_, Tx, Rx>
where
Tx: stm_spi::TxDma<SUBGHZSPI>,
Rx: stm_spi::RxDma<SUBGHZSPI>,
{
type Error = SpiDeviceError;
}

impl<Tx, Rx> spi::SpiDevice for SubGhzSpiDevice<'_, Tx, Rx>
where
Tx: stm_spi::TxDma<SUBGHZSPI>,
Rx: stm_spi::RxDma<SUBGHZSPI>,
{
async fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
pac::PWR.subghzspicr().modify(|w| w.set_nss(false));

let op_res: Result<(), Self::Error> = try {
for op in operations {
match op {
Operation::Read(buf) => self.bus.read(buf).await.map_err(SpiDeviceError::Spi)?,
Operation::Write(buf) => self.bus.write(buf).await.map_err(SpiDeviceError::Spi)?,
Operation::Transfer(read, write) => {
self.bus.transfer(read, write).await.map_err(SpiDeviceError::Spi)?
}
Operation::TransferInPlace(buf) => {
self.bus.transfer_in_place(buf).await.map_err(SpiDeviceError::Spi)?
}
#[cfg(not(feature = "time"))]
Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported)?,
#[cfg(feature = "time")]
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
}
}
};

pac::PWR.subghzspicr().modify(|w| w.set_nss(true));

op_res
}
}
3 changes: 3 additions & 0 deletions examples/stm32wl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ chrono = { version = "^0.4", default-features = false }

[profile.release]
debug = 2

[patch.crates-io]
lora-phy = { git = "https://github.com/CBJamo/lora-phy.git", branch = "SpiDevice" }
4 changes: 2 additions & 2 deletions examples/stm32wl/src/bin/lora_lorawan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_lora::stm32wl::SubGhzSpiDevice;
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::time::Hertz;
use embassy_stm32::{bind_interrupts, peripherals};
use embassy_time::Delay;
Expand Down Expand Up @@ -53,7 +53,7 @@ async fn main(_spawner: Spawner) {
}
let p = embassy_stm32::init(config);

let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);
let spi = SubGhzSpiDevice::new(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.PC4.degrade(), Level::Low, Speed::High);
Expand Down
4 changes: 2 additions & 2 deletions examples/stm32wl/src/bin/lora_p2p_receive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_lora::stm32wl::SubGhzSpiDevice;
use embassy_stm32::bind_interrupts;
use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::spi::Spi;
use embassy_stm32::time::Hertz;
use embassy_time::{Delay, Timer};
use lora_phy::mod_params::*;
Expand Down Expand Up @@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
}
let p = embassy_stm32::init(config);

let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);
let spi = SubGhzSpiDevice::new(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.PC4.degrade(), Level::Low, Speed::High);
Expand Down
4 changes: 2 additions & 2 deletions examples/stm32wl/src/bin/lora_p2p_send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_lora::stm32wl::SubGhzSpiDevice;
use embassy_stm32::bind_interrupts;
use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::spi::Spi;
use embassy_stm32::time::Hertz;
use embassy_time::Delay;
use lora_phy::mod_params::*;
Expand Down Expand Up @@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
}
let p = embassy_stm32::init(config);

let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);
let spi = SubGhzSpiDevice::new(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.PC4.degrade(), Level::Low, Speed::High);
Expand Down

0 comments on commit 674a373

Please sign in to comment.