diff options
| -rw-r--r-- | embassy-lora/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-lora/src/sx127x/mod.rs | 85 | ||||
| -rw-r--r-- | embassy-lora/src/sx127x/sx127x_lora/mod.rs | 373 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 5 | ||||
| -rw-r--r-- | examples/stm32l0/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/stm32l0/src/bin/lorawan.rs | 17 | ||||
| -rw-r--r-- | examples/stm32wl55/Cargo.toml | 4 |
8 files changed, 269 insertions, 233 deletions
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index fa46d43f5..024eb6aaf 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml | |||
| @@ -23,5 +23,5 @@ futures = { version = "0.3.17", default-features = false, features = [ "async-aw | |||
| 23 | embedded-hal = { version = "0.2", features = ["unproven"] } | 23 | embedded-hal = { version = "0.2", features = ["unproven"] } |
| 24 | bit_field = { version = "0.10" } | 24 | bit_field = { version = "0.10" } |
| 25 | 25 | ||
| 26 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } | 26 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] } |
| 27 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false } | 27 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false } |
diff --git a/embassy-lora/src/sx127x/mod.rs b/embassy-lora/src/sx127x/mod.rs index a9736b85f..7d3280e05 100644 --- a/embassy-lora/src/sx127x/mod.rs +++ b/embassy-lora/src/sx127x/mod.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | use core::future::Future; | 1 | use core::future::Future; |
| 2 | use embassy::traits::gpio::WaitForRisingEdge; | 2 | use embassy::traits::gpio::WaitForRisingEdge; |
| 3 | use embedded_hal::blocking::delay::DelayMs; | 3 | use embassy::traits::spi::*; |
| 4 | use embedded_hal::blocking::spi::{Transfer, Write}; | ||
| 5 | use embedded_hal::digital::v2::OutputPin; | 4 | use embedded_hal::digital::v2::OutputPin; |
| 6 | use lorawan_device::async_device::{ | 5 | use lorawan_device::async_device::{ |
| 7 | radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig}, | 6 | radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig}, |
| @@ -21,7 +20,7 @@ pub trait RadioSwitch { | |||
| 21 | /// Semtech Sx127x radio peripheral | 20 | /// Semtech Sx127x radio peripheral |
| 22 | pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS> | 21 | pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS> |
| 23 | where | 22 | where |
| 24 | SPI: Transfer<u8, Error = E> + Write<u8, Error = E> + 'static, | 23 | SPI: FullDuplex<u8, Error = E> + 'static, |
| 25 | E: 'static, | 24 | E: 'static, |
| 26 | CS: OutputPin + 'static, | 25 | CS: OutputPin + 'static, |
| 27 | RESET: OutputPin + 'static, | 26 | RESET: OutputPin + 'static, |
| @@ -43,29 +42,29 @@ pub enum State { | |||
| 43 | 42 | ||
| 44 | impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS> | 43 | impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS> |
| 45 | where | 44 | where |
| 46 | SPI: Transfer<u8, Error = E> + Write<u8, Error = E> + 'static, | 45 | SPI: FullDuplex<u8, Error = E> + 'static, |
| 47 | CS: OutputPin + 'static, | 46 | CS: OutputPin + 'static, |
| 48 | RESET: OutputPin + 'static, | 47 | RESET: OutputPin + 'static, |
| 49 | I: WaitForRisingEdge + 'static, | 48 | I: WaitForRisingEdge + 'static, |
| 50 | RFS: RadioSwitch + 'static, | 49 | RFS: RadioSwitch + 'static, |
| 50 | E: 'static, | ||
| 51 | { | 51 | { |
| 52 | pub fn new<D: DelayMs<u32>>( | 52 | pub async fn new( |
| 53 | spi: SPI, | 53 | spi: SPI, |
| 54 | cs: CS, | 54 | cs: CS, |
| 55 | reset: RESET, | 55 | reset: RESET, |
| 56 | irq: I, | 56 | irq: I, |
| 57 | rfs: RFS, | 57 | rfs: RFS, |
| 58 | d: &mut D, | ||
| 59 | ) -> Result<Self, RadioError<E, CS::Error, RESET::Error>> { | 58 | ) -> Result<Self, RadioError<E, CS::Error, RESET::Error>> { |
| 60 | let mut radio = LoRa::new(spi, cs, reset); | 59 | let mut radio = LoRa::new(spi, cs, reset); |
| 61 | radio.reset(d)?; | 60 | radio.reset().await?; |
| 62 | Ok(Self { radio, irq, rfs }) | 61 | Ok(Self { radio, irq, rfs }) |
| 63 | } | 62 | } |
| 64 | } | 63 | } |
| 65 | 64 | ||
| 66 | impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS> | 65 | impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS> |
| 67 | where | 66 | where |
| 68 | SPI: Transfer<u8, Error = E> + Write<u8, Error = E> + 'static, | 67 | SPI: FullDuplex<u8, Error = E> + 'static, |
| 69 | CS: OutputPin + 'static, | 68 | CS: OutputPin + 'static, |
| 70 | RESET: OutputPin + 'static, | 69 | RESET: OutputPin + 'static, |
| 71 | I: WaitForRisingEdge + 'static, | 70 | I: WaitForRisingEdge + 'static, |
| @@ -81,7 +80,7 @@ where | |||
| 81 | 80 | ||
| 82 | impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS> | 81 | impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS> |
| 83 | where | 82 | where |
| 84 | SPI: Transfer<u8, Error = E> + Write<u8, Error = E> + 'static, | 83 | SPI: FullDuplex<u8, Error = E> + 'static, |
| 85 | CS: OutputPin + 'static, | 84 | CS: OutputPin + 'static, |
| 86 | E: 'static, | 85 | E: 'static, |
| 87 | RESET: OutputPin + 'static, | 86 | RESET: OutputPin + 'static, |
| @@ -96,29 +95,33 @@ where | |||
| 96 | fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> { | 95 | fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> { |
| 97 | trace!("TX START"); | 96 | trace!("TX START"); |
| 98 | async move { | 97 | async move { |
| 98 | self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap(); | ||
| 99 | self.rfs.set_tx(); | 99 | self.rfs.set_tx(); |
| 100 | self.radio.set_tx_power(14, 0)?; | 100 | self.radio.set_tx_power(14, 0).await?; |
| 101 | self.radio.set_frequency(config.rf.frequency)?; | 101 | self.radio.set_frequency(config.rf.frequency).await?; |
| 102 | // TODO: Modify radio to support other coding rates | 102 | // TODO: Modify radio to support other coding rates |
| 103 | self.radio.set_coding_rate_4(5)?; | 103 | self.radio.set_coding_rate_4(5).await?; |
| 104 | self.radio | 104 | self.radio |
| 105 | .set_signal_bandwidth(bandwidth_to_i64(config.rf.bandwidth))?; | 105 | .set_signal_bandwidth(bandwidth_to_i64(config.rf.bandwidth)) |
| 106 | .await?; | ||
| 106 | self.radio | 107 | self.radio |
| 107 | .set_spreading_factor(spreading_factor_to_u8(config.rf.spreading_factor))?; | 108 | .set_spreading_factor(spreading_factor_to_u8(config.rf.spreading_factor)) |
| 109 | .await?; | ||
| 110 | |||
| 111 | self.radio.set_preamble_length(8).await?; | ||
| 112 | self.radio.set_lora_pa_ramp().await?; | ||
| 113 | self.radio.set_lora_sync_word().await?; | ||
| 114 | self.radio.set_invert_iq(false).await?; | ||
| 115 | self.radio.set_crc(true).await?; | ||
| 108 | 116 | ||
| 109 | self.radio.set_preamble_length(8)?; | 117 | self.radio.set_dio0_tx_done().await?; |
| 110 | self.radio.set_lora_pa_ramp()?; | ||
| 111 | self.radio.set_lora_sync_word()?; | ||
| 112 | self.radio.set_invert_iq(false)?; | ||
| 113 | self.radio.set_crc(true)?; | ||
| 114 | 118 | ||
| 115 | self.radio.set_dio0_tx_done()?; | 119 | self.radio.transmit_start(buf).await?; |
| 116 | self.radio.transmit_payload(buf)?; | ||
| 117 | 120 | ||
| 118 | loop { | 121 | loop { |
| 119 | self.irq.wait_for_rising_edge().await; | 122 | self.irq.wait_for_rising_edge().await; |
| 120 | self.radio.set_mode(RadioMode::Stdby).ok().unwrap(); | 123 | self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap(); |
| 121 | let irq = self.radio.clear_irq().ok().unwrap(); | 124 | let irq = self.radio.clear_irq().await.ok().unwrap(); |
| 122 | if (irq & IRQ::IrqTxDoneMask.addr()) != 0 { | 125 | if (irq & IRQ::IrqTxDoneMask.addr()) != 0 { |
| 123 | trace!("TX DONE"); | 126 | trace!("TX DONE"); |
| 124 | return Ok(0); | 127 | return Ok(0); |
| @@ -134,32 +137,34 @@ where | |||
| 134 | trace!("RX START"); | 137 | trace!("RX START"); |
| 135 | async move { | 138 | async move { |
| 136 | self.rfs.set_rx(); | 139 | self.rfs.set_rx(); |
| 137 | self.radio.reset_payload_length()?; | 140 | self.radio.reset_payload_length().await?; |
| 138 | self.radio.set_frequency(config.frequency)?; | 141 | self.radio.set_frequency(config.frequency).await?; |
| 139 | // TODO: Modify radio to support other coding rates | 142 | // TODO: Modify radio to support other coding rates |
| 140 | self.radio.set_coding_rate_4(5)?; | 143 | self.radio.set_coding_rate_4(5).await?; |
| 141 | self.radio | 144 | self.radio |
| 142 | .set_signal_bandwidth(bandwidth_to_i64(config.bandwidth))?; | 145 | .set_signal_bandwidth(bandwidth_to_i64(config.bandwidth)) |
| 146 | .await?; | ||
| 143 | self.radio | 147 | self.radio |
| 144 | .set_spreading_factor(spreading_factor_to_u8(config.spreading_factor))?; | 148 | .set_spreading_factor(spreading_factor_to_u8(config.spreading_factor)) |
| 149 | .await?; | ||
| 145 | 150 | ||
| 146 | self.radio.set_preamble_length(8)?; | 151 | self.radio.set_preamble_length(8).await?; |
| 147 | self.radio.set_lora_sync_word()?; | 152 | self.radio.set_lora_sync_word().await?; |
| 148 | self.radio.set_invert_iq(true)?; | 153 | self.radio.set_invert_iq(true).await?; |
| 149 | self.radio.set_crc(true)?; | 154 | self.radio.set_crc(true).await?; |
| 150 | 155 | ||
| 151 | self.radio.set_dio0_rx_done()?; | 156 | self.radio.set_dio0_rx_done().await?; |
| 152 | self.radio.set_mode(RadioMode::RxContinuous)?; | 157 | self.radio.set_mode(RadioMode::RxContinuous).await?; |
| 153 | 158 | ||
| 154 | loop { | 159 | loop { |
| 155 | self.irq.wait_for_rising_edge().await; | 160 | self.irq.wait_for_rising_edge().await; |
| 156 | self.radio.set_mode(RadioMode::Stdby).ok().unwrap(); | 161 | self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap(); |
| 157 | let irq = self.radio.clear_irq().ok().unwrap(); | 162 | let irq = self.radio.clear_irq().await.ok().unwrap(); |
| 158 | if (irq & IRQ::IrqRxDoneMask.addr()) != 0 { | 163 | if (irq & IRQ::IrqRxDoneMask.addr()) != 0 { |
| 159 | let rssi = self.radio.get_packet_rssi().unwrap_or(0) as i16; | 164 | let rssi = self.radio.get_packet_rssi().await.unwrap_or(0) as i16; |
| 160 | let snr = self.radio.get_packet_snr().unwrap_or(0.0) as i8; | 165 | let snr = self.radio.get_packet_snr().await.unwrap_or(0.0) as i8; |
| 161 | let response = if let Ok(size) = self.radio.read_packet_size() { | 166 | let response = if let Ok(size) = self.radio.read_packet_size().await { |
| 162 | self.radio.read_packet(buf)?; | 167 | self.radio.read_packet(buf).await?; |
| 163 | Ok((size, RxQuality::new(rssi, snr))) | 168 | Ok((size, RxQuality::new(rssi, snr))) |
| 164 | } else { | 169 | } else { |
| 165 | Ok((0, RxQuality::new(rssi, snr))) | 170 | Ok((0, RxQuality::new(rssi, snr))) |
diff --git a/embassy-lora/src/sx127x/sx127x_lora/mod.rs b/embassy-lora/src/sx127x/sx127x_lora/mod.rs index c541815fe..a903779ca 100644 --- a/embassy-lora/src/sx127x/sx127x_lora/mod.rs +++ b/embassy-lora/src/sx127x/sx127x_lora/mod.rs | |||
| @@ -6,24 +6,15 @@ | |||
| 6 | #![allow(dead_code)] | 6 | #![allow(dead_code)] |
| 7 | 7 | ||
| 8 | use bit_field::BitField; | 8 | use bit_field::BitField; |
| 9 | use embedded_hal::blocking::{ | 9 | use embassy::time::{Duration, Timer}; |
| 10 | delay::DelayMs, | 10 | use embassy::traits::spi::*; |
| 11 | spi::{Transfer, Write}, | ||
| 12 | }; | ||
| 13 | use embedded_hal::digital::v2::OutputPin; | 11 | use embedded_hal::digital::v2::OutputPin; |
| 14 | use embedded_hal::spi::{Mode, Phase, Polarity}; | ||
| 15 | 12 | ||
| 16 | mod register; | 13 | mod register; |
| 17 | use self::register::PaConfig; | 14 | use self::register::PaConfig; |
| 18 | use self::register::Register; | 15 | use self::register::Register; |
| 19 | pub use self::register::IRQ; | 16 | pub use self::register::IRQ; |
| 20 | 17 | ||
| 21 | /// Provides the necessary SPI mode configuration for the radio | ||
| 22 | pub const MODE: Mode = Mode { | ||
| 23 | phase: Phase::CaptureOnSecondTransition, | ||
| 24 | polarity: Polarity::IdleHigh, | ||
| 25 | }; | ||
| 26 | |||
| 27 | /// Provides high-level access to Semtech SX1276/77/78/79 based boards connected to a Raspberry Pi | 18 | /// Provides high-level access to Semtech SX1276/77/78/79 based boards connected to a Raspberry Pi |
| 28 | pub struct LoRa<SPI, CS, RESET> { | 19 | pub struct LoRa<SPI, CS, RESET> { |
| 29 | spi: SPI, | 20 | spi: SPI, |
| @@ -56,7 +47,7 @@ const VERSION_CHECK: u8 = 0x09; | |||
| 56 | 47 | ||
| 57 | impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> | 48 | impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> |
| 58 | where | 49 | where |
| 59 | SPI: Transfer<u8, Error = E> + Write<u8, Error = E>, | 50 | SPI: FullDuplex<u8, Error = E>, |
| 60 | CS: OutputPin, | 51 | CS: OutputPin, |
| 61 | RESET: OutputPin, | 52 | RESET: OutputPin, |
| 62 | { | 53 | { |
| @@ -72,24 +63,25 @@ where | |||
| 72 | } | 63 | } |
| 73 | } | 64 | } |
| 74 | 65 | ||
| 75 | pub fn reset<D: DelayMs<u32>>( | 66 | pub async fn reset(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 76 | &mut self, | ||
| 77 | d: &mut D, | ||
| 78 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 79 | self.reset.set_low().map_err(Reset)?; | 67 | self.reset.set_low().map_err(Reset)?; |
| 80 | d.delay_ms(10_u32); | 68 | Timer::after(Duration::from_millis(10)).await; |
| 81 | self.reset.set_high().map_err(Reset)?; | 69 | self.reset.set_high().map_err(Reset)?; |
| 82 | d.delay_ms(10_u32); | 70 | Timer::after(Duration::from_millis(10)).await; |
| 83 | let version = self.read_register(Register::RegVersion.addr())?; | 71 | let version = self.read_register(Register::RegVersion.addr()).await?; |
| 84 | if version == VERSION_CHECK { | 72 | if version == VERSION_CHECK { |
| 85 | self.set_mode(RadioMode::Sleep)?; | 73 | self.set_mode(RadioMode::Sleep).await?; |
| 86 | self.write_register(Register::RegFifoTxBaseAddr.addr(), 0)?; | 74 | self.write_register(Register::RegFifoTxBaseAddr.addr(), 0) |
| 87 | self.write_register(Register::RegFifoRxBaseAddr.addr(), 0)?; | 75 | .await?; |
| 88 | let lna = self.read_register(Register::RegLna.addr())?; | 76 | self.write_register(Register::RegFifoRxBaseAddr.addr(), 0) |
| 89 | self.write_register(Register::RegLna.addr(), lna | 0x03)?; | 77 | .await?; |
| 90 | self.write_register(Register::RegModemConfig3.addr(), 0x04)?; | 78 | let lna = self.read_register(Register::RegLna.addr()).await?; |
| 91 | self.set_tcxo(true)?; | 79 | self.write_register(Register::RegLna.addr(), lna | 0x03) |
| 92 | self.set_mode(RadioMode::Stdby)?; | 80 | .await?; |
| 81 | self.write_register(Register::RegModemConfig3.addr(), 0x04) | ||
| 82 | .await?; | ||
| 83 | self.set_tcxo(true).await?; | ||
| 84 | self.set_mode(RadioMode::Stdby).await?; | ||
| 93 | self.cs.set_high().map_err(CS)?; | 85 | self.cs.set_high().map_err(CS)?; |
| 94 | Ok(()) | 86 | Ok(()) |
| 95 | } else { | 87 | } else { |
| @@ -97,137 +89,125 @@ where | |||
| 97 | } | 89 | } |
| 98 | } | 90 | } |
| 99 | 91 | ||
| 100 | /// Transmits up to 255 bytes of data. To avoid the use of an allocator, this takes a fixed 255 u8 | 92 | pub async fn set_dio0_tx_done(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 101 | /// array and a payload size and returns the number of bytes sent if successful. | 93 | self.write_register(Register::RegIrqFlagsMask.addr(), 0b1111_0111) |
| 102 | pub fn transmit_payload_busy( | 94 | .await?; |
| 103 | &mut self, | 95 | let mapping = self.read_register(Register::RegDioMapping1.addr()).await?; |
| 104 | buffer: [u8; 255], | ||
| 105 | payload_size: usize, | ||
| 106 | ) -> Result<usize, Error<E, CS::Error, RESET::Error>> { | ||
| 107 | if self.transmitting()? { | ||
| 108 | Err(Transmitting) | ||
| 109 | } else { | ||
| 110 | self.set_mode(RadioMode::Stdby)?; | ||
| 111 | if self.explicit_header { | ||
| 112 | self.set_explicit_header_mode()?; | ||
| 113 | } else { | ||
| 114 | self.set_implicit_header_mode()?; | ||
| 115 | } | ||
| 116 | |||
| 117 | self.write_register(Register::RegIrqFlags.addr(), 0)?; | ||
| 118 | self.write_register(Register::RegFifoAddrPtr.addr(), 0)?; | ||
| 119 | self.write_register(Register::RegPayloadLength.addr(), 0)?; | ||
| 120 | for byte in buffer.iter().take(payload_size) { | ||
| 121 | self.write_register(Register::RegFifo.addr(), *byte)?; | ||
| 122 | } | ||
| 123 | self.write_register(Register::RegPayloadLength.addr(), payload_size as u8)?; | ||
| 124 | self.set_mode(RadioMode::Tx)?; | ||
| 125 | while self.transmitting()? {} | ||
| 126 | Ok(payload_size) | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | pub fn set_dio0_tx_done(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 131 | self.write_register(Register::RegIrqFlagsMask.addr(), 0b1111_0111)?; | ||
| 132 | let mapping = self.read_register(Register::RegDioMapping1.addr())?; | ||
| 133 | self.write_register(Register::RegDioMapping1.addr(), (mapping & 0x3F) | 0x40) | 96 | self.write_register(Register::RegDioMapping1.addr(), (mapping & 0x3F) | 0x40) |
| 97 | .await | ||
| 134 | } | 98 | } |
| 135 | 99 | ||
| 136 | pub fn set_dio0_rx_done(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 100 | pub async fn set_dio0_rx_done(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 137 | self.write_register(Register::RegIrqFlagsMask.addr(), 0b0001_1111)?; | 101 | self.write_register(Register::RegIrqFlagsMask.addr(), 0b0001_1111) |
| 138 | let mapping = self.read_register(Register::RegDioMapping1.addr())?; | 102 | .await?; |
| 103 | let mapping = self.read_register(Register::RegDioMapping1.addr()).await?; | ||
| 139 | self.write_register(Register::RegDioMapping1.addr(), mapping & 0x3F) | 104 | self.write_register(Register::RegDioMapping1.addr(), mapping & 0x3F) |
| 105 | .await | ||
| 140 | } | 106 | } |
| 141 | 107 | ||
| 142 | pub fn transmit_payload( | 108 | pub async fn transmit_start( |
| 143 | &mut self, | 109 | &mut self, |
| 144 | buffer: &[u8], | 110 | buffer: &[u8], |
| 145 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 111 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 146 | assert!(buffer.len() < 255); | 112 | assert!(buffer.len() < 255); |
| 147 | if self.transmitting()? { | 113 | if self.transmitting().await? { |
| 114 | //trace!("ALREADY TRANSMNITTING"); | ||
| 148 | Err(Transmitting) | 115 | Err(Transmitting) |
| 149 | } else { | 116 | } else { |
| 150 | self.set_mode(RadioMode::Stdby)?; | 117 | self.set_mode(RadioMode::Stdby).await?; |
| 151 | if self.explicit_header { | 118 | if self.explicit_header { |
| 152 | self.set_explicit_header_mode()?; | 119 | self.set_explicit_header_mode().await?; |
| 153 | } else { | 120 | } else { |
| 154 | self.set_implicit_header_mode()?; | 121 | self.set_implicit_header_mode().await?; |
| 155 | } | 122 | } |
| 156 | 123 | ||
| 157 | self.write_register(Register::RegIrqFlags.addr(), 0)?; | 124 | self.write_register(Register::RegIrqFlags.addr(), 0).await?; |
| 158 | self.write_register(Register::RegFifoAddrPtr.addr(), 0)?; | 125 | self.write_register(Register::RegFifoAddrPtr.addr(), 0) |
| 159 | self.write_register(Register::RegPayloadLength.addr(), 0)?; | 126 | .await?; |
| 127 | self.write_register(Register::RegPayloadLength.addr(), 0) | ||
| 128 | .await?; | ||
| 160 | for byte in buffer.iter() { | 129 | for byte in buffer.iter() { |
| 161 | self.write_register(Register::RegFifo.addr(), *byte)?; | 130 | self.write_register(Register::RegFifo.addr(), *byte).await?; |
| 162 | } | 131 | } |
| 163 | self.write_register(Register::RegPayloadLength.addr(), buffer.len() as u8)?; | 132 | self.write_register(Register::RegPayloadLength.addr(), buffer.len() as u8) |
| 164 | self.set_mode(RadioMode::Tx)?; | 133 | .await?; |
| 134 | self.set_mode(RadioMode::Tx).await?; | ||
| 165 | Ok(()) | 135 | Ok(()) |
| 166 | } | 136 | } |
| 167 | } | 137 | } |
| 168 | 138 | ||
| 169 | pub fn packet_ready(&mut self) -> Result<bool, Error<E, CS::Error, RESET::Error>> { | 139 | pub async fn packet_ready(&mut self) -> Result<bool, Error<E, CS::Error, RESET::Error>> { |
| 170 | Ok(self.read_register(Register::RegIrqFlags.addr())?.get_bit(6)) | 140 | Ok(self |
| 141 | .read_register(Register::RegIrqFlags.addr()) | ||
| 142 | .await? | ||
| 143 | .get_bit(6)) | ||
| 171 | } | 144 | } |
| 172 | 145 | ||
| 173 | pub fn irq_flags_mask(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 146 | pub async fn irq_flags_mask(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 174 | Ok(self.read_register(Register::RegIrqFlagsMask.addr())? as u8) | 147 | Ok(self.read_register(Register::RegIrqFlagsMask.addr()).await? as u8) |
| 175 | } | 148 | } |
| 176 | 149 | ||
| 177 | pub fn irq_flags(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 150 | pub async fn irq_flags(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 178 | Ok(self.read_register(Register::RegIrqFlags.addr())? as u8) | 151 | Ok(self.read_register(Register::RegIrqFlags.addr()).await? as u8) |
| 179 | } | 152 | } |
| 180 | 153 | ||
| 181 | pub fn read_packet_size(&mut self) -> Result<usize, Error<E, CS::Error, RESET::Error>> { | 154 | pub async fn read_packet_size(&mut self) -> Result<usize, Error<E, CS::Error, RESET::Error>> { |
| 182 | let size = self.read_register(Register::RegRxNbBytes.addr())?; | 155 | let size = self.read_register(Register::RegRxNbBytes.addr()).await?; |
| 183 | Ok(size as usize) | 156 | Ok(size as usize) |
| 184 | } | 157 | } |
| 185 | 158 | ||
| 186 | /// Returns the contents of the fifo as a fixed 255 u8 array. This should only be called is there is a | 159 | /// Returns the contents of the fifo as a fixed 255 u8 array. This should only be called is there is a |
| 187 | /// new packet ready to be read. | 160 | /// new packet ready to be read. |
| 188 | pub fn read_packet( | 161 | pub async fn read_packet( |
| 189 | &mut self, | 162 | &mut self, |
| 190 | buffer: &mut [u8], | 163 | buffer: &mut [u8], |
| 191 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 164 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 192 | self.clear_irq()?; | 165 | self.clear_irq().await?; |
| 193 | let size = self.read_register(Register::RegRxNbBytes.addr())?; | 166 | let size = self.read_register(Register::RegRxNbBytes.addr()).await?; |
| 194 | assert!(size as usize <= buffer.len()); | 167 | assert!(size as usize <= buffer.len()); |
| 195 | let fifo_addr = self.read_register(Register::RegFifoRxCurrentAddr.addr())?; | 168 | let fifo_addr = self |
| 196 | self.write_register(Register::RegFifoAddrPtr.addr(), fifo_addr)?; | 169 | .read_register(Register::RegFifoRxCurrentAddr.addr()) |
| 170 | .await?; | ||
| 171 | self.write_register(Register::RegFifoAddrPtr.addr(), fifo_addr) | ||
| 172 | .await?; | ||
| 197 | for i in 0..size { | 173 | for i in 0..size { |
| 198 | let byte = self.read_register(Register::RegFifo.addr())?; | 174 | let byte = self.read_register(Register::RegFifo.addr()).await?; |
| 199 | buffer[i as usize] = byte; | 175 | buffer[i as usize] = byte; |
| 200 | } | 176 | } |
| 201 | self.write_register(Register::RegFifoAddrPtr.addr(), 0)?; | 177 | self.write_register(Register::RegFifoAddrPtr.addr(), 0) |
| 178 | .await?; | ||
| 202 | Ok(()) | 179 | Ok(()) |
| 203 | } | 180 | } |
| 204 | 181 | ||
| 205 | /// Returns true if the radio is currently transmitting a packet. | 182 | /// Returns true if the radio is currently transmitting a packet. |
| 206 | pub fn transmitting(&mut self) -> Result<bool, Error<E, CS::Error, RESET::Error>> { | 183 | pub async fn transmitting(&mut self) -> Result<bool, Error<E, CS::Error, RESET::Error>> { |
| 207 | if (self.read_register(Register::RegOpMode.addr())? & RadioMode::Tx.addr()) | 184 | if (self.read_register(Register::RegOpMode.addr()).await?) & RadioMode::Tx.addr() |
| 208 | == RadioMode::Tx.addr() | 185 | == RadioMode::Tx.addr() |
| 209 | { | 186 | { |
| 210 | Ok(true) | 187 | Ok(true) |
| 211 | } else { | 188 | } else { |
| 212 | if (self.read_register(Register::RegIrqFlags.addr())? & IRQ::IrqTxDoneMask.addr()) == 1 | 189 | if (self.read_register(Register::RegIrqFlags.addr()).await? & IRQ::IrqTxDoneMask.addr()) |
| 190 | == 1 | ||
| 213 | { | 191 | { |
| 214 | self.write_register(Register::RegIrqFlags.addr(), IRQ::IrqTxDoneMask.addr())?; | 192 | self.write_register(Register::RegIrqFlags.addr(), IRQ::IrqTxDoneMask.addr()) |
| 193 | .await?; | ||
| 215 | } | 194 | } |
| 216 | Ok(false) | 195 | Ok(false) |
| 217 | } | 196 | } |
| 218 | } | 197 | } |
| 219 | 198 | ||
| 220 | /// Clears the radio's IRQ registers. | 199 | /// Clears the radio's IRQ registers. |
| 221 | pub fn clear_irq(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 200 | pub async fn clear_irq(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 222 | let irq_flags = self.read_register(Register::RegIrqFlags.addr())?; | 201 | let irq_flags = self.read_register(Register::RegIrqFlags.addr()).await?; |
| 223 | self.write_register(Register::RegIrqFlags.addr(), 0xFF)?; | 202 | self.write_register(Register::RegIrqFlags.addr(), 0xFF) |
| 203 | .await?; | ||
| 224 | Ok(irq_flags) | 204 | Ok(irq_flags) |
| 225 | } | 205 | } |
| 226 | 206 | ||
| 227 | /// Sets the transmit power and pin. Levels can range from 0-14 when the output | 207 | /// Sets the transmit power and pin. Levels can range from 0-14 when the output |
| 228 | /// pin = 0(RFO), and form 0-20 when output pin = 1(PaBoost). Power is in dB. | 208 | /// pin = 0(RFO), and form 0-20 when output pin = 1(PaBoost). Power is in dB. |
| 229 | /// Default value is `17`. | 209 | /// Default value is `17`. |
| 230 | pub fn set_tx_power( | 210 | pub async fn set_tx_power( |
| 231 | &mut self, | 211 | &mut self, |
| 232 | mut level: i32, | 212 | mut level: i32, |
| 233 | output_pin: u8, | 213 | output_pin: u8, |
| @@ -240,6 +220,7 @@ where | |||
| 240 | level = 14; | 220 | level = 14; |
| 241 | } | 221 | } |
| 242 | self.write_register(Register::RegPaConfig.addr(), (0x70 | level) as u8) | 222 | self.write_register(Register::RegPaConfig.addr(), (0x70 | level) as u8) |
| 223 | .await | ||
| 243 | } else { | 224 | } else { |
| 244 | // PA BOOST | 225 | // PA BOOST |
| 245 | if level > 17 { | 226 | if level > 17 { |
| @@ -250,30 +231,31 @@ where | |||
| 250 | level -= 3; | 231 | level -= 3; |
| 251 | 232 | ||
| 252 | // High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.) | 233 | // High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.) |
| 253 | self.write_register(Register::RegPaDac.addr(), 0x87)?; | 234 | self.write_register(Register::RegPaDac.addr(), 0x87).await?; |
| 254 | self.set_ocp(140)?; | 235 | self.set_ocp(140).await?; |
| 255 | } else { | 236 | } else { |
| 256 | if level < 2 { | 237 | if level < 2 { |
| 257 | level = 2; | 238 | level = 2; |
| 258 | } | 239 | } |
| 259 | //Default value PA_HF/LF or +17dBm | 240 | //Default value PA_HF/LF or +17dBm |
| 260 | self.write_register(Register::RegPaDac.addr(), 0x84)?; | 241 | self.write_register(Register::RegPaDac.addr(), 0x84).await?; |
| 261 | self.set_ocp(100)?; | 242 | self.set_ocp(100).await?; |
| 262 | } | 243 | } |
| 263 | level -= 2; | 244 | level -= 2; |
| 264 | self.write_register( | 245 | self.write_register( |
| 265 | Register::RegPaConfig.addr(), | 246 | Register::RegPaConfig.addr(), |
| 266 | PaConfig::PaBoost.addr() | level as u8, | 247 | PaConfig::PaBoost.addr() | level as u8, |
| 267 | ) | 248 | ) |
| 249 | .await | ||
| 268 | } | 250 | } |
| 269 | } | 251 | } |
| 270 | 252 | ||
| 271 | pub fn get_modem_stat(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 253 | pub async fn get_modem_stat(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 272 | Ok(self.read_register(Register::RegModemStat.addr())? as u8) | 254 | Ok(self.read_register(Register::RegModemStat.addr()).await? as u8) |
| 273 | } | 255 | } |
| 274 | 256 | ||
| 275 | /// Sets the over current protection on the radio(mA). | 257 | /// Sets the over current protection on the radio(mA). |
| 276 | pub fn set_ocp(&mut self, ma: u8) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 258 | pub async fn set_ocp(&mut self, ma: u8) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 277 | let mut ocp_trim: u8 = 27; | 259 | let mut ocp_trim: u8 = 27; |
| 278 | 260 | ||
| 279 | if ma <= 120 { | 261 | if ma <= 120 { |
| @@ -282,31 +264,40 @@ where | |||
| 282 | ocp_trim = (ma + 30) / 10; | 264 | ocp_trim = (ma + 30) / 10; |
| 283 | } | 265 | } |
| 284 | self.write_register(Register::RegOcp.addr(), 0x20 | (0x1F & ocp_trim)) | 266 | self.write_register(Register::RegOcp.addr(), 0x20 | (0x1F & ocp_trim)) |
| 267 | .await | ||
| 285 | } | 268 | } |
| 286 | 269 | ||
| 287 | /// Sets the state of the radio. Default mode after initiation is `Standby`. | 270 | /// Sets the state of the radio. Default mode after initiation is `Standby`. |
| 288 | pub fn set_mode(&mut self, mode: RadioMode) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 271 | pub async fn set_mode( |
| 272 | &mut self, | ||
| 273 | mode: RadioMode, | ||
| 274 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 289 | if self.explicit_header { | 275 | if self.explicit_header { |
| 290 | self.set_explicit_header_mode()?; | 276 | self.set_explicit_header_mode().await?; |
| 291 | } else { | 277 | } else { |
| 292 | self.set_implicit_header_mode()?; | 278 | self.set_implicit_header_mode().await?; |
| 293 | } | 279 | } |
| 294 | self.write_register( | 280 | self.write_register( |
| 295 | Register::RegOpMode.addr(), | 281 | Register::RegOpMode.addr(), |
| 296 | RadioMode::LongRangeMode.addr() | mode.addr(), | 282 | RadioMode::LongRangeMode.addr() | mode.addr(), |
| 297 | )?; | 283 | ) |
| 284 | .await?; | ||
| 298 | 285 | ||
| 299 | self.mode = mode; | 286 | self.mode = mode; |
| 300 | Ok(()) | 287 | Ok(()) |
| 301 | } | 288 | } |
| 302 | 289 | ||
| 303 | pub fn reset_payload_length(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 290 | pub async fn reset_payload_length(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 304 | self.write_register(Register::RegPayloadLength.addr(), 0xFF) | 291 | self.write_register(Register::RegPayloadLength.addr(), 0xFF) |
| 292 | .await | ||
| 305 | } | 293 | } |
| 306 | 294 | ||
| 307 | /// Sets the frequency of the radio. Values are in megahertz. | 295 | /// Sets the frequency of the radio. Values are in megahertz. |
| 308 | /// I.E. 915 MHz must be used for North America. Check regulation for your area. | 296 | /// I.E. 915 MHz must be used for North America. Check regulation for your area. |
| 309 | pub fn set_frequency(&mut self, freq: u32) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 297 | pub async fn set_frequency( |
| 298 | &mut self, | ||
| 299 | freq: u32, | ||
| 300 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 310 | const FREQ_STEP: f64 = 61.03515625; | 301 | const FREQ_STEP: f64 = 61.03515625; |
| 311 | // calculate register values | 302 | // calculate register values |
| 312 | let frf = (freq as f64 / FREQ_STEP) as u32; | 303 | let frf = (freq as f64 / FREQ_STEP) as u32; |
| @@ -314,23 +305,28 @@ where | |||
| 314 | self.write_register( | 305 | self.write_register( |
| 315 | Register::RegFrfMsb.addr(), | 306 | Register::RegFrfMsb.addr(), |
| 316 | ((frf & 0x00FF_0000) >> 16) as u8, | 307 | ((frf & 0x00FF_0000) >> 16) as u8, |
| 317 | )?; | 308 | ) |
| 318 | self.write_register(Register::RegFrfMid.addr(), ((frf & 0x0000_FF00) >> 8) as u8)?; | 309 | .await?; |
| 310 | self.write_register(Register::RegFrfMid.addr(), ((frf & 0x0000_FF00) >> 8) as u8) | ||
| 311 | .await?; | ||
| 319 | self.write_register(Register::RegFrfLsb.addr(), (frf & 0x0000_00FF) as u8) | 312 | self.write_register(Register::RegFrfLsb.addr(), (frf & 0x0000_00FF) as u8) |
| 313 | .await | ||
| 320 | } | 314 | } |
| 321 | 315 | ||
| 322 | /// Sets the radio to use an explicit header. Default state is `ON`. | 316 | /// Sets the radio to use an explicit header. Default state is `ON`. |
| 323 | fn set_explicit_header_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 317 | async fn set_explicit_header_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 324 | let reg_modem_config_1 = self.read_register(Register::RegModemConfig1.addr())?; | 318 | let reg_modem_config_1 = self.read_register(Register::RegModemConfig1.addr()).await?; |
| 325 | self.write_register(Register::RegModemConfig1.addr(), reg_modem_config_1 & 0xfe)?; | 319 | self.write_register(Register::RegModemConfig1.addr(), reg_modem_config_1 & 0xfe) |
| 320 | .await?; | ||
| 326 | self.explicit_header = true; | 321 | self.explicit_header = true; |
| 327 | Ok(()) | 322 | Ok(()) |
| 328 | } | 323 | } |
| 329 | 324 | ||
| 330 | /// Sets the radio to use an implicit header. Default state is `OFF`. | 325 | /// Sets the radio to use an implicit header. Default state is `OFF`. |
| 331 | fn set_implicit_header_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 326 | async fn set_implicit_header_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 332 | let reg_modem_config_1 = self.read_register(Register::RegModemConfig1.addr())?; | 327 | let reg_modem_config_1 = self.read_register(Register::RegModemConfig1.addr()).await?; |
| 333 | self.write_register(Register::RegModemConfig1.addr(), reg_modem_config_1 & 0x01)?; | 328 | self.write_register(Register::RegModemConfig1.addr(), reg_modem_config_1 & 0x01) |
| 329 | .await?; | ||
| 334 | self.explicit_header = false; | 330 | self.explicit_header = false; |
| 335 | Ok(()) | 331 | Ok(()) |
| 336 | } | 332 | } |
| @@ -338,7 +334,7 @@ where | |||
| 338 | /// Sets the spreading factor of the radio. Supported values are between 6 and 12. | 334 | /// Sets the spreading factor of the radio. Supported values are between 6 and 12. |
| 339 | /// If a spreading factor of 6 is set, implicit header mode must be used to transmit | 335 | /// If a spreading factor of 6 is set, implicit header mode must be used to transmit |
| 340 | /// and receive packets. Default value is `7`. | 336 | /// and receive packets. Default value is `7`. |
| 341 | pub fn set_spreading_factor( | 337 | pub async fn set_spreading_factor( |
| 342 | &mut self, | 338 | &mut self, |
| 343 | mut sf: u8, | 339 | mut sf: u8, |
| 344 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 340 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| @@ -349,36 +345,45 @@ where | |||
| 349 | } | 345 | } |
| 350 | 346 | ||
| 351 | if sf == 6 { | 347 | if sf == 6 { |
| 352 | self.write_register(Register::RegDetectionOptimize.addr(), 0xc5)?; | 348 | self.write_register(Register::RegDetectionOptimize.addr(), 0xc5) |
| 353 | self.write_register(Register::RegDetectionThreshold.addr(), 0x0c)?; | 349 | .await?; |
| 350 | self.write_register(Register::RegDetectionThreshold.addr(), 0x0c) | ||
| 351 | .await?; | ||
| 354 | } else { | 352 | } else { |
| 355 | self.write_register(Register::RegDetectionOptimize.addr(), 0xc3)?; | 353 | self.write_register(Register::RegDetectionOptimize.addr(), 0xc3) |
| 356 | self.write_register(Register::RegDetectionThreshold.addr(), 0x0a)?; | 354 | .await?; |
| 355 | self.write_register(Register::RegDetectionThreshold.addr(), 0x0a) | ||
| 356 | .await?; | ||
| 357 | } | 357 | } |
| 358 | let modem_config_2 = self.read_register(Register::RegModemConfig2.addr())?; | 358 | let modem_config_2 = self.read_register(Register::RegModemConfig2.addr()).await?; |
| 359 | self.write_register( | 359 | self.write_register( |
| 360 | Register::RegModemConfig2.addr(), | 360 | Register::RegModemConfig2.addr(), |
| 361 | (modem_config_2 & 0x0f) | ((sf << 4) & 0xf0), | 361 | (modem_config_2 & 0x0f) | ((sf << 4) & 0xf0), |
| 362 | )?; | 362 | ) |
| 363 | self.set_ldo_flag()?; | 363 | .await?; |
| 364 | self.set_ldo_flag().await?; | ||
| 364 | 365 | ||
| 365 | self.write_register(Register::RegSymbTimeoutLsb.addr(), 0x05)?; | 366 | self.write_register(Register::RegSymbTimeoutLsb.addr(), 0x05) |
| 367 | .await?; | ||
| 366 | 368 | ||
| 367 | Ok(()) | 369 | Ok(()) |
| 368 | } | 370 | } |
| 369 | 371 | ||
| 370 | pub fn set_tcxo(&mut self, external: bool) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 372 | pub async fn set_tcxo( |
| 373 | &mut self, | ||
| 374 | external: bool, | ||
| 375 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 371 | if external { | 376 | if external { |
| 372 | self.write_register(Register::RegTcxo.addr(), 0x10) | 377 | self.write_register(Register::RegTcxo.addr(), 0x10).await |
| 373 | } else { | 378 | } else { |
| 374 | self.write_register(Register::RegTcxo.addr(), 0x00) | 379 | self.write_register(Register::RegTcxo.addr(), 0x00).await |
| 375 | } | 380 | } |
| 376 | } | 381 | } |
| 377 | 382 | ||
| 378 | /// Sets the signal bandwidth of the radio. Supported values are: `7800 Hz`, `10400 Hz`, | 383 | /// Sets the signal bandwidth of the radio. Supported values are: `7800 Hz`, `10400 Hz`, |
| 379 | /// `15600 Hz`, `20800 Hz`, `31250 Hz`,`41700 Hz` ,`62500 Hz`,`125000 Hz` and `250000 Hz` | 384 | /// `15600 Hz`, `20800 Hz`, `31250 Hz`,`41700 Hz` ,`62500 Hz`,`125000 Hz` and `250000 Hz` |
| 380 | /// Default value is `125000 Hz` | 385 | /// Default value is `125000 Hz` |
| 381 | pub fn set_signal_bandwidth( | 386 | pub async fn set_signal_bandwidth( |
| 382 | &mut self, | 387 | &mut self, |
| 383 | sbw: i64, | 388 | sbw: i64, |
| 384 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 389 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| @@ -394,19 +399,20 @@ where | |||
| 394 | 250_000 => 8, | 399 | 250_000 => 8, |
| 395 | _ => 9, | 400 | _ => 9, |
| 396 | }; | 401 | }; |
| 397 | let modem_config_1 = self.read_register(Register::RegModemConfig1.addr())?; | 402 | let modem_config_1 = self.read_register(Register::RegModemConfig1.addr()).await?; |
| 398 | self.write_register( | 403 | self.write_register( |
| 399 | Register::RegModemConfig1.addr(), | 404 | Register::RegModemConfig1.addr(), |
| 400 | (modem_config_1 & 0x0f) | ((bw << 4) as u8), | 405 | (modem_config_1 & 0x0f) | ((bw << 4) as u8), |
| 401 | )?; | 406 | ) |
| 402 | self.set_ldo_flag()?; | 407 | .await?; |
| 408 | self.set_ldo_flag().await?; | ||
| 403 | Ok(()) | 409 | Ok(()) |
| 404 | } | 410 | } |
| 405 | 411 | ||
| 406 | /// Sets the coding rate of the radio with the numerator fixed at 4. Supported values | 412 | /// Sets the coding rate of the radio with the numerator fixed at 4. Supported values |
| 407 | /// are between `5` and `8`, these correspond to coding rates of `4/5` and `4/8`. | 413 | /// are between `5` and `8`, these correspond to coding rates of `4/5` and `4/8`. |
| 408 | /// Default value is `5`. | 414 | /// Default value is `5`. |
| 409 | pub fn set_coding_rate_4( | 415 | pub async fn set_coding_rate_4( |
| 410 | &mut self, | 416 | &mut self, |
| 411 | mut denominator: u8, | 417 | mut denominator: u8, |
| 412 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 418 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| @@ -416,52 +422,64 @@ where | |||
| 416 | denominator = 8; | 422 | denominator = 8; |
| 417 | } | 423 | } |
| 418 | let cr = denominator - 4; | 424 | let cr = denominator - 4; |
| 419 | let modem_config_1 = self.read_register(Register::RegModemConfig1.addr())?; | 425 | let modem_config_1 = self.read_register(Register::RegModemConfig1.addr()).await?; |
| 420 | self.write_register( | 426 | self.write_register( |
| 421 | Register::RegModemConfig1.addr(), | 427 | Register::RegModemConfig1.addr(), |
| 422 | (modem_config_1 & 0xf1) | (cr << 1), | 428 | (modem_config_1 & 0xf1) | (cr << 1), |
| 423 | ) | 429 | ) |
| 430 | .await | ||
| 424 | } | 431 | } |
| 425 | 432 | ||
| 426 | /// Sets the preamble length of the radio. Values are between 6 and 65535. | 433 | /// Sets the preamble length of the radio. Values are between 6 and 65535. |
| 427 | /// Default value is `8`. | 434 | /// Default value is `8`. |
| 428 | pub fn set_preamble_length( | 435 | pub async fn set_preamble_length( |
| 429 | &mut self, | 436 | &mut self, |
| 430 | length: i64, | 437 | length: i64, |
| 431 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 438 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 432 | self.write_register(Register::RegPreambleMsb.addr(), (length >> 8) as u8)?; | 439 | self.write_register(Register::RegPreambleMsb.addr(), (length >> 8) as u8) |
| 440 | .await?; | ||
| 433 | self.write_register(Register::RegPreambleLsb.addr(), length as u8) | 441 | self.write_register(Register::RegPreambleLsb.addr(), length as u8) |
| 442 | .await | ||
| 434 | } | 443 | } |
| 435 | 444 | ||
| 436 | /// Enables are disables the radio's CRC check. Default value is `false`. | 445 | /// Enables are disables the radio's CRC check. Default value is `false`. |
| 437 | pub fn set_crc(&mut self, value: bool) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 446 | pub async fn set_crc(&mut self, value: bool) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 438 | let modem_config_2 = self.read_register(Register::RegModemConfig2.addr())?; | 447 | let modem_config_2 = self.read_register(Register::RegModemConfig2.addr()).await?; |
| 439 | if value { | 448 | if value { |
| 440 | self.write_register(Register::RegModemConfig2.addr(), modem_config_2 | 0x04) | 449 | self.write_register(Register::RegModemConfig2.addr(), modem_config_2 | 0x04) |
| 450 | .await | ||
| 441 | } else { | 451 | } else { |
| 442 | self.write_register(Register::RegModemConfig2.addr(), modem_config_2 & 0xfb) | 452 | self.write_register(Register::RegModemConfig2.addr(), modem_config_2 & 0xfb) |
| 453 | .await | ||
| 443 | } | 454 | } |
| 444 | } | 455 | } |
| 445 | 456 | ||
| 446 | /// Inverts the radio's IQ signals. Default value is `false`. | 457 | /// Inverts the radio's IQ signals. Default value is `false`. |
| 447 | pub fn set_invert_iq(&mut self, value: bool) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 458 | pub async fn set_invert_iq( |
| 459 | &mut self, | ||
| 460 | value: bool, | ||
| 461 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | ||
| 448 | if value { | 462 | if value { |
| 449 | self.write_register(Register::RegInvertiq.addr(), 0x66)?; | 463 | self.write_register(Register::RegInvertiq.addr(), 0x66) |
| 464 | .await?; | ||
| 450 | self.write_register(Register::RegInvertiq2.addr(), 0x19) | 465 | self.write_register(Register::RegInvertiq2.addr(), 0x19) |
| 466 | .await | ||
| 451 | } else { | 467 | } else { |
| 452 | self.write_register(Register::RegInvertiq.addr(), 0x27)?; | 468 | self.write_register(Register::RegInvertiq.addr(), 0x27) |
| 469 | .await?; | ||
| 453 | self.write_register(Register::RegInvertiq2.addr(), 0x1d) | 470 | self.write_register(Register::RegInvertiq2.addr(), 0x1d) |
| 471 | .await | ||
| 454 | } | 472 | } |
| 455 | } | 473 | } |
| 456 | 474 | ||
| 457 | /// Returns the spreading factor of the radio. | 475 | /// Returns the spreading factor of the radio. |
| 458 | pub fn get_spreading_factor(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 476 | pub async fn get_spreading_factor(&mut self) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 459 | Ok(self.read_register(Register::RegModemConfig2.addr())? >> 4) | 477 | Ok(self.read_register(Register::RegModemConfig2.addr()).await? >> 4) |
| 460 | } | 478 | } |
| 461 | 479 | ||
| 462 | /// Returns the signal bandwidth of the radio. | 480 | /// Returns the signal bandwidth of the radio. |
| 463 | pub fn get_signal_bandwidth(&mut self) -> Result<i64, Error<E, CS::Error, RESET::Error>> { | 481 | pub async fn get_signal_bandwidth(&mut self) -> Result<i64, Error<E, CS::Error, RESET::Error>> { |
| 464 | let bw = self.read_register(Register::RegModemConfig1.addr())? >> 4; | 482 | let bw = self.read_register(Register::RegModemConfig1.addr()).await? >> 4; |
| 465 | let bw = match bw { | 483 | let bw = match bw { |
| 466 | 0 => 7_800, | 484 | 0 => 7_800, |
| 467 | 1 => 10_400, | 485 | 1 => 10_400, |
| @@ -479,69 +497,76 @@ where | |||
| 479 | } | 497 | } |
| 480 | 498 | ||
| 481 | /// Returns the RSSI of the last received packet. | 499 | /// Returns the RSSI of the last received packet. |
| 482 | pub fn get_packet_rssi(&mut self) -> Result<i32, Error<E, CS::Error, RESET::Error>> { | 500 | pub async fn get_packet_rssi(&mut self) -> Result<i32, Error<E, CS::Error, RESET::Error>> { |
| 483 | Ok(i32::from(self.read_register(Register::RegPktRssiValue.addr())?) - 157) | 501 | Ok(i32::from(self.read_register(Register::RegPktRssiValue.addr()).await?) - 157) |
| 484 | } | 502 | } |
| 485 | 503 | ||
| 486 | /// Returns the signal to noise radio of the the last received packet. | 504 | /// Returns the signal to noise radio of the the last received packet. |
| 487 | pub fn get_packet_snr(&mut self) -> Result<f64, Error<E, CS::Error, RESET::Error>> { | 505 | pub async fn get_packet_snr(&mut self) -> Result<f64, Error<E, CS::Error, RESET::Error>> { |
| 488 | Ok(f64::from( | 506 | Ok(f64::from( |
| 489 | self.read_register(Register::RegPktSnrValue.addr())?, | 507 | self.read_register(Register::RegPktSnrValue.addr()).await?, |
| 490 | )) | 508 | )) |
| 491 | } | 509 | } |
| 492 | 510 | ||
| 493 | /// Returns the frequency error of the last received packet in Hz. | 511 | /// Returns the frequency error of the last received packet in Hz. |
| 494 | pub fn get_packet_frequency_error(&mut self) -> Result<i64, Error<E, CS::Error, RESET::Error>> { | 512 | pub async fn get_packet_frequency_error( |
| 513 | &mut self, | ||
| 514 | ) -> Result<i64, Error<E, CS::Error, RESET::Error>> { | ||
| 495 | let mut freq_error: i32; | 515 | let mut freq_error: i32; |
| 496 | freq_error = i32::from(self.read_register(Register::RegFreqErrorMsb.addr())? & 0x7); | 516 | freq_error = i32::from(self.read_register(Register::RegFreqErrorMsb.addr()).await? & 0x7); |
| 497 | freq_error <<= 8i64; | 517 | freq_error <<= 8i64; |
| 498 | freq_error += i32::from(self.read_register(Register::RegFreqErrorMid.addr())?); | 518 | freq_error += i32::from(self.read_register(Register::RegFreqErrorMid.addr()).await?); |
| 499 | freq_error <<= 8i64; | 519 | freq_error <<= 8i64; |
| 500 | freq_error += i32::from(self.read_register(Register::RegFreqErrorLsb.addr())?); | 520 | freq_error += i32::from(self.read_register(Register::RegFreqErrorLsb.addr()).await?); |
| 501 | 521 | ||
| 502 | let f_xtal = 32_000_000; // FXOSC: crystal oscillator (XTAL) frequency (2.5. Chip Specification, p. 14) | 522 | let f_xtal = 32_000_000; // FXOSC: crystal oscillator (XTAL) frequency (2.5. Chip Specification, p. 14) |
| 503 | let f_error = ((f64::from(freq_error) * (1i64 << 24) as f64) / f64::from(f_xtal)) | 523 | let f_error = ((f64::from(freq_error) * (1i64 << 24) as f64) / f64::from(f_xtal)) |
| 504 | * (self.get_signal_bandwidth()? as f64 / 500_000.0f64); // p. 37 | 524 | * (self.get_signal_bandwidth().await? as f64 / 500_000.0f64); // p. 37 |
| 505 | Ok(f_error as i64) | 525 | Ok(f_error as i64) |
| 506 | } | 526 | } |
| 507 | 527 | ||
| 508 | fn set_ldo_flag(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 528 | async fn set_ldo_flag(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 509 | let sw = self.get_signal_bandwidth()?; | 529 | let sw = self.get_signal_bandwidth().await?; |
| 510 | // Section 4.1.1.5 | 530 | // Section 4.1.1.5 |
| 511 | let symbol_duration = 1000 / (sw / ((1_i64) << self.get_spreading_factor()?)); | 531 | let symbol_duration = 1000 / (sw / ((1_i64) << self.get_spreading_factor().await?)); |
| 512 | 532 | ||
| 513 | // Section 4.1.1.6 | 533 | // Section 4.1.1.6 |
| 514 | let ldo_on = symbol_duration > 16; | 534 | let ldo_on = symbol_duration > 16; |
| 515 | 535 | ||
| 516 | let mut config_3 = self.read_register(Register::RegModemConfig3.addr())?; | 536 | let mut config_3 = self.read_register(Register::RegModemConfig3.addr()).await?; |
| 517 | config_3.set_bit(3, ldo_on); | 537 | config_3.set_bit(3, ldo_on); |
| 518 | //config_3.set_bit(2, true); | 538 | //config_3.set_bit(2, true); |
| 519 | self.write_register(Register::RegModemConfig3.addr(), config_3) | 539 | self.write_register(Register::RegModemConfig3.addr(), config_3) |
| 540 | .await | ||
| 520 | } | 541 | } |
| 521 | 542 | ||
| 522 | fn read_register(&mut self, reg: u8) -> Result<u8, Error<E, CS::Error, RESET::Error>> { | 543 | async fn read_register(&mut self, reg: u8) -> Result<u8, Error<E, CS::Error, RESET::Error>> { |
| 544 | let mut buffer = [reg & 0x7f, 0]; | ||
| 523 | self.cs.set_low().map_err(CS)?; | 545 | self.cs.set_low().map_err(CS)?; |
| 524 | 546 | ||
| 525 | let mut buffer = [reg & 0x7f, 0]; | 547 | let _ = self |
| 526 | let transfer = self.spi.transfer(&mut buffer).map_err(SPI)?; | 548 | .spi |
| 549 | .read_write(&mut buffer, &[reg & 0x7f, 0]) | ||
| 550 | .await | ||
| 551 | .map_err(SPI)?; | ||
| 552 | |||
| 527 | self.cs.set_high().map_err(CS)?; | 553 | self.cs.set_high().map_err(CS)?; |
| 528 | Ok(transfer[1]) | 554 | Ok(buffer[1]) |
| 529 | } | 555 | } |
| 530 | 556 | ||
| 531 | fn write_register( | 557 | async fn write_register( |
| 532 | &mut self, | 558 | &mut self, |
| 533 | reg: u8, | 559 | reg: u8, |
| 534 | byte: u8, | 560 | byte: u8, |
| 535 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 561 | ) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 536 | self.cs.set_low().map_err(CS)?; | 562 | self.cs.set_low().map_err(CS)?; |
| 537 | |||
| 538 | let buffer = [reg | 0x80, byte]; | 563 | let buffer = [reg | 0x80, byte]; |
| 539 | self.spi.write(&buffer).map_err(SPI)?; | 564 | self.spi.write(&buffer).await.map_err(SPI)?; |
| 540 | self.cs.set_high().map_err(CS)?; | 565 | self.cs.set_high().map_err(CS)?; |
| 541 | Ok(()) | 566 | Ok(()) |
| 542 | } | 567 | } |
| 543 | 568 | ||
| 544 | pub fn put_in_fsk_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 569 | pub async fn put_in_fsk_mode(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 545 | // Put in FSK mode | 570 | // Put in FSK mode |
| 546 | let mut op_mode = 0; | 571 | let mut op_mode = 0; |
| 547 | op_mode | 572 | op_mode |
| @@ -551,9 +576,10 @@ where | |||
| 551 | .set_bits(0..2, 0b011); // Mode | 576 | .set_bits(0..2, 0b011); // Mode |
| 552 | 577 | ||
| 553 | self.write_register(Register::RegOpMode as u8, op_mode) | 578 | self.write_register(Register::RegOpMode as u8, op_mode) |
| 579 | .await | ||
| 554 | } | 580 | } |
| 555 | 581 | ||
| 556 | pub fn set_fsk_pa_ramp( | 582 | pub async fn set_fsk_pa_ramp( |
| 557 | &mut self, | 583 | &mut self, |
| 558 | modulation_shaping: FskDataModulationShaping, | 584 | modulation_shaping: FskDataModulationShaping, |
| 559 | ramp: FskRampUpRamDown, | 585 | ramp: FskRampUpRamDown, |
| @@ -564,14 +590,15 @@ where | |||
| 564 | .set_bits(0..3, ramp as u8); | 590 | .set_bits(0..3, ramp as u8); |
| 565 | 591 | ||
| 566 | self.write_register(Register::RegPaRamp as u8, pa_ramp) | 592 | self.write_register(Register::RegPaRamp as u8, pa_ramp) |
| 593 | .await | ||
| 567 | } | 594 | } |
| 568 | 595 | ||
| 569 | pub fn set_lora_pa_ramp(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 596 | pub async fn set_lora_pa_ramp(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 570 | self.write_register(Register::RegPaRamp as u8, 0b1000) | 597 | self.write_register(Register::RegPaRamp as u8, 0b1000).await |
| 571 | } | 598 | } |
| 572 | 599 | ||
| 573 | pub fn set_lora_sync_word(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { | 600 | pub async fn set_lora_sync_word(&mut self) -> Result<(), Error<E, CS::Error, RESET::Error>> { |
| 574 | self.write_register(Register::RegSyncWord as u8, 0x34) | 601 | self.write_register(Register::RegSyncWord as u8, 0x34).await |
| 575 | } | 602 | } |
| 576 | } | 603 | } |
| 577 | /// Modes of the radio and their corresponding register values. | 604 | /// Modes of the radio and their corresponding register values. |
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 83ff70009..aa04fcca4 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs | |||
| @@ -262,6 +262,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 262 | T::regs().cr2().modify(|reg| { | 262 | T::regs().cr2().modify(|reg| { |
| 263 | reg.set_rxdmaen(true); | 263 | reg.set_rxdmaen(true); |
| 264 | }); | 264 | }); |
| 265 | |||
| 266 | // Flush the read buffer to avoid errornous data from being read | ||
| 267 | while T::regs().sr().read().rxne() { | ||
| 268 | let _ = T::regs().dr().read(); | ||
| 269 | } | ||
| 265 | } | 270 | } |
| 266 | Self::set_word_size(WordSize::EightBit); | 271 | Self::set_word_size(WordSize::EightBit); |
| 267 | 272 | ||
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index e8ef33176..dbd9d78c9 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -284,6 +284,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 284 | T::regs().cfg1().modify(|reg| { | 284 | T::regs().cfg1().modify(|reg| { |
| 285 | reg.set_rxdmaen(true); | 285 | reg.set_rxdmaen(true); |
| 286 | }); | 286 | }); |
| 287 | |||
| 288 | // Flush the read buffer to avoid errornous data from being read | ||
| 289 | while T::regs().sr().read().rxp() { | ||
| 290 | let _ = T::regs().rxdr().read(); | ||
| 291 | } | ||
| 287 | } | 292 | } |
| 288 | 293 | ||
| 289 | let rx_request = self.rxdma.request(); | 294 | let rx_request = self.rxdma.request(); |
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 6fe744f03..53ba6ba39 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -10,16 +10,17 @@ embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | |||
| 10 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | 10 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-tim3"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-tim3"] } |
| 12 | 12 | ||
| 13 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time"] } | 13 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] } |
| 14 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } | 14 | |
| 15 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["default-crypto"] } | 15 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] } |
| 16 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["default-crypto"] } | ||
| 16 | 17 | ||
| 17 | defmt = "0.3" | 18 | defmt = "0.3" |
| 18 | defmt-rtt = "0.3" | 19 | defmt-rtt = "0.3" |
| 19 | 20 | ||
| 20 | cortex-m = "0.7.3" | 21 | cortex-m = "0.7.3" |
| 21 | cortex-m-rt = "0.7.0" | 22 | cortex-m-rt = "0.7.0" |
| 22 | embedded-hal = "0.2.6" | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 25 | heapless = { version = "0.7.5", default-features = false } | 25 | heapless = { version = "0.7.5", default-features = false } |
| 26 | embedded-hal = "0.2.6" | ||
diff --git a/examples/stm32l0/src/bin/lorawan.rs b/examples/stm32l0/src/bin/lorawan.rs index 5ca69f9a7..cbae88356 100644 --- a/examples/stm32l0/src/bin/lorawan.rs +++ b/examples/stm32l0/src/bin/lorawan.rs | |||
| @@ -12,7 +12,6 @@ mod example_common; | |||
| 12 | use embassy_lora::{sx127x::*, LoraTimer}; | 12 | use embassy_lora::{sx127x::*, LoraTimer}; |
| 13 | use embassy_stm32::{ | 13 | use embassy_stm32::{ |
| 14 | dbgmcu::Dbgmcu, | 14 | dbgmcu::Dbgmcu, |
| 15 | dma::NoDma, | ||
| 16 | exti::ExtiInput, | 15 | exti::ExtiInput, |
| 17 | gpio::{Input, Level, Output, Pull, Speed}, | 16 | gpio::{Input, Level, Output, Pull, Speed}, |
| 18 | rcc, | 17 | rcc, |
| @@ -45,8 +44,8 @@ async fn main(_spawner: embassy::executor::Spawner, mut p: Peripherals) { | |||
| 45 | p.PB3, | 44 | p.PB3, |
| 46 | p.PA7, | 45 | p.PA7, |
| 47 | p.PA6, | 46 | p.PA6, |
| 48 | NoDma, | 47 | p.DMA1_CH3, |
| 49 | NoDma, | 48 | p.DMA1_CH2, |
| 50 | 200_000.hz(), | 49 | 200_000.hz(), |
| 51 | spi::Config::default(), | 50 | spi::Config::default(), |
| 52 | ); | 51 | ); |
| @@ -58,15 +57,9 @@ async fn main(_spawner: embassy::executor::Spawner, mut p: Peripherals) { | |||
| 58 | let ready = Input::new(p.PB4, Pull::Up); | 57 | let ready = Input::new(p.PB4, Pull::Up); |
| 59 | let ready_pin = ExtiInput::new(ready, p.EXTI4); | 58 | let ready_pin = ExtiInput::new(ready, p.EXTI4); |
| 60 | 59 | ||
| 61 | let radio = Sx127xRadio::new( | 60 | let radio = Sx127xRadio::new(spi, cs, reset, ready_pin, DummySwitch) |
| 62 | spi, | 61 | .await |
| 63 | cs, | 62 | .unwrap(); |
| 64 | reset, | ||
| 65 | ready_pin, | ||
| 66 | DummySwitch, | ||
| 67 | &mut embassy::time::Delay, | ||
| 68 | ) | ||
| 69 | .unwrap(); | ||
| 70 | 63 | ||
| 71 | let region = region::EU868::default().into(); | 64 | let region = region::EU868::default().into(); |
| 72 | let mut radio_buffer = [0; 256]; | 65 | let mut radio_buffer = [0; 256]; |
diff --git a/examples/stm32wl55/Cargo.toml b/examples/stm32wl55/Cargo.toml index 7a7621230..c7344152d 100644 --- a/examples/stm32wl55/Cargo.toml +++ b/examples/stm32wl55/Cargo.toml | |||
| @@ -11,8 +11,8 @@ embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = | |||
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] } |
| 12 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } | 12 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } |
| 13 | 13 | ||
| 14 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } | 14 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] } |
| 15 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["default-crypto"] } | 15 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["default-crypto"] } |
| 16 | 16 | ||
| 17 | defmt = "0.3" | 17 | defmt = "0.3" |
| 18 | defmt-rtt = "0.3" | 18 | defmt-rtt = "0.3" |
