aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-12-06 08:35:11 +0000
committerGitHub <[email protected]>2021-12-06 08:35:11 +0000
commit7c155c3abaee8aea32896e20ce14bce6efa1eb1b (patch)
treef8b664399b29b8c988472599e6c399092ff75369
parent6d6e6f55b8a9ecd38b5a6d3bb11f74b2654afdeb (diff)
parent81ec4c82fdd89798edc1eda764017b5e81184401 (diff)
Merge #514
514: Refactor sx127x driver to use async SPI r=lulf a=lulf It also contains a fix to SPI DMA transfer/read_write operations to ensure MISO doesn't contain any old data. Co-authored-by: Ulf Lilleengen <[email protected]>
-rw-r--r--embassy-lora/Cargo.toml4
-rw-r--r--embassy-lora/src/sx127x/mod.rs85
-rw-r--r--embassy-lora/src/sx127x/sx127x_lora/mod.rs373
-rw-r--r--embassy-stm32/src/spi/v2.rs5
-rw-r--r--embassy-stm32/src/spi/v3.rs5
-rw-r--r--examples/stm32l0/Cargo.toml9
-rw-r--r--examples/stm32l0/src/bin/lorawan.rs17
-rw-r--r--examples/stm32wl55/Cargo.toml4
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
23embedded-hal = { version = "0.2", features = ["unproven"] } 23embedded-hal = { version = "0.2", features = ["unproven"] }
24bit_field = { version = "0.10" } 24bit_field = { version = "0.10" }
25 25
26lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } 26lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] }
27lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false } 27lorawan-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 @@
1use core::future::Future; 1use core::future::Future;
2use embassy::traits::gpio::WaitForRisingEdge; 2use embassy::traits::gpio::WaitForRisingEdge;
3use embedded_hal::blocking::delay::DelayMs; 3use embassy::traits::spi::*;
4use embedded_hal::blocking::spi::{Transfer, Write};
5use embedded_hal::digital::v2::OutputPin; 4use embedded_hal::digital::v2::OutputPin;
6use lorawan_device::async_device::{ 5use 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
22pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS> 21pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS>
23where 22where
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
44impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS> 43impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS>
45where 44where
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
66impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS> 65impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
67where 66where
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
82impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS> 81impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
83where 82where
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
8use bit_field::BitField; 8use bit_field::BitField;
9use embedded_hal::blocking::{ 9use embassy::time::{Duration, Timer};
10 delay::DelayMs, 10use embassy::traits::spi::*;
11 spi::{Transfer, Write},
12};
13use embedded_hal::digital::v2::OutputPin; 11use embedded_hal::digital::v2::OutputPin;
14use embedded_hal::spi::{Mode, Phase, Polarity};
15 12
16mod register; 13mod register;
17use self::register::PaConfig; 14use self::register::PaConfig;
18use self::register::Register; 15use self::register::Register;
19pub use self::register::IRQ; 16pub use self::register::IRQ;
20 17
21/// Provides the necessary SPI mode configuration for the radio
22pub 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
28pub struct LoRa<SPI, CS, RESET> { 19pub struct LoRa<SPI, CS, RESET> {
29 spi: SPI, 20 spi: SPI,
@@ -56,7 +47,7 @@ const VERSION_CHECK: u8 = 0x09;
56 47
57impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> 48impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
58where 49where
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"] }
10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } 10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-tim3"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-tim3"] }
12 12
13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time"] } 13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] }
14lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } 14
15lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["default-crypto"] } 15lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] }
16lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["default-crypto"] }
16 17
17defmt = "0.3" 18defmt = "0.3"
18defmt-rtt = "0.3" 19defmt-rtt = "0.3"
19 20
20cortex-m = "0.7.3" 21cortex-m = "0.7.3"
21cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
22embedded-hal = "0.2.6"
23panic-probe = { version = "0.3", features = ["print-defmt"] } 23panic-probe = { version = "0.3", features = ["print-defmt"] }
24futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 24futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
25heapless = { version = "0.7.5", default-features = false } 25heapless = { version = "0.7.5", default-features = false }
26embedded-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;
12use embassy_lora::{sx127x::*, LoraTimer}; 12use embassy_lora::{sx127x::*, LoraTimer};
13use embassy_stm32::{ 13use 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 =
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] }
12embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } 12embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] }
13 13
14lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["async"] } 14lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["async"] }
15lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "4bff2e0021103adfbccedcbf49dbcd0474adc4b2", default-features = false, features = ["default-crypto"] } 15lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "53d2feb43e2f3ddcdc55f0587391b0d3f02d8d93", default-features = false, features = ["default-crypto"] }
16 16
17defmt = "0.3" 17defmt = "0.3"
18defmt-rtt = "0.3" 18defmt-rtt = "0.3"