aboutsummaryrefslogtreecommitdiff
path: root/embassy-lora
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2022-06-25 11:59:07 +0200
committerTimo Kröger <[email protected]>2022-08-26 15:44:58 +0200
commitf31116cafaeea7746aec19903fb1c73adaea9ea6 (patch)
tree8f735abceb824e60f757290062ff99428407b530 /embassy-lora
parent69d80c086d2f22f66aa25fafb55918cb1c5e3bdd (diff)
lora: Make some options configurable
Call `config()` only once at construction not with every RX and TX operation. The Lora-E5 only supports HP mode, use that instead. The nucleo board supports both HP and LP and should continue to work.
Diffstat (limited to 'embassy-lora')
-rw-r--r--embassy-lora/src/stm32wl/mod.rs75
1 files changed, 37 insertions, 38 deletions
diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs
index 7502dc379..5170b261a 100644
--- a/embassy-lora/src/stm32wl/mod.rs
+++ b/embassy-lora/src/stm32wl/mod.rs
@@ -6,9 +6,9 @@ use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
6use embassy_stm32::dma::NoDma; 6use embassy_stm32::dma::NoDma;
7use embassy_stm32::interrupt::{Interrupt, InterruptExt, SUBGHZ_RADIO}; 7use embassy_stm32::interrupt::{Interrupt, InterruptExt, SUBGHZ_RADIO};
8use embassy_stm32::subghz::{ 8use embassy_stm32::subghz::{
9 CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, Irq, LoRaBandwidth, LoRaModParams, LoRaPacketParams, 9 CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, HseTrim, Irq, LoRaBandwidth, LoRaModParams,
10 LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk, 10 LoRaPacketParams, LoRaSyncWord, Ocp, PaConfig, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF,
11 Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams, 11 StandbyClk, Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
12}; 12};
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14use futures::future::poll_fn; 14use futures::future::poll_fn;
@@ -61,46 +61,17 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
61 unsafe { SUBGHZ_RADIO::steal().disable() }; 61 unsafe { SUBGHZ_RADIO::steal().disable() };
62 }); 62 });
63 63
64 Self { radio, switch, irq } 64 configure_radio(&mut radio, config)?;
65 }
66
67 /// Configure radio settings in preparation for TX or RX
68 pub(crate) fn configure(&mut self) -> Result<(), RadioError> {
69 trace!("Configuring STM32WL SUBGHZ radio");
70 self.radio.set_standby(StandbyClk::Rc)?;
71 let tcxo_mode = TcxoMode::new()
72 .set_txco_trim(TcxoTrim::Volts1pt7)
73 .set_timeout(Timeout::from_duration_sat(core::time::Duration::from_millis(40)));
74
75 self.radio.set_tcxo_mode(&tcxo_mode)?;
76 self.radio.set_regulator_mode(RegMode::Ldo)?;
77
78 self.radio.calibrate_image(CalibrateImage::ISM_863_870)?;
79
80 self.radio.set_buffer_base_address(0, 0)?;
81
82 self.radio
83 .set_pa_config(&PaConfig::new().set_pa_duty_cycle(0x1).set_hp_max(0x0).set_pa(PaSel::Lp))?;
84 65
85 self.radio.set_pa_ocp(Ocp::Max140m)?; 66 Ok(Self { radio, switch, irq })
86
87 // let tx_params = TxParams::LP_14.set_ramp_time(RampTime::Micros40);
88 self.radio
89 .set_tx_params(&TxParams::new().set_ramp_time(RampTime::Micros40).set_power(0x0A))?;
90
91 self.radio.set_packet_type(PacketType::LoRa)?;
92 self.radio.set_lora_sync_word(LoRaSyncWord::Public)?;
93 trace!("Done initializing STM32WL SUBGHZ radio");
94 Ok(())
95 } 67 }
96 68
97 /// Perform a transmission with the given parameters and payload. Returns any time adjustements needed form 69 /// Perform a transmission with the given parameters and payload. Returns any time adjustements needed form
98 /// the upcoming RX window start. 70 /// the upcoming RX window start.
99 async fn do_tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, RadioError> { 71 async fn do_tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, RadioError> {
100 //trace!("TX Request: {}", config); 72 trace!("TX Request: {}", config);
101 trace!("TX START"); 73 //trace!("TX START");
102 self.switch.set_tx(); 74 self.switch.set_tx();
103 self.configure()?;
104 75
105 self.radio 76 self.radio
106 .set_rf_frequency(&RfFreq::from_frequency(config.rf.frequency))?; 77 .set_rf_frequency(&RfFreq::from_frequency(config.rf.frequency))?;
@@ -164,7 +135,6 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
164 trace!("RX START"); 135 trace!("RX START");
165 // trace!("Starting RX: {}", config); 136 // trace!("Starting RX: {}", config);
166 self.switch.set_rx(); 137 self.switch.set_rx();
167 self.configure()?;
168 138
169 self.radio.set_rf_frequency(&RfFreq::from_frequency(config.frequency))?; 139 self.radio.set_rf_frequency(&RfFreq::from_frequency(config.frequency))?;
170 140
@@ -180,7 +150,7 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
180 150
181 let irq_cfg = CfgIrq::new() 151 let irq_cfg = CfgIrq::new()
182 .irq_enable_all(Irq::RxDone) 152 .irq_enable_all(Irq::RxDone)
183 .irq_enable_all(Irq::PreambleDetected) 153 //.irq_enable_all(Irq::PreambleDetected)
184 .irq_enable_all(Irq::HeaderErr) 154 .irq_enable_all(Irq::HeaderErr)
185 .irq_enable_all(Irq::Timeout) 155 .irq_enable_all(Irq::Timeout)
186 .irq_enable_all(Irq::Err); 156 .irq_enable_all(Irq::Err);
@@ -235,6 +205,35 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
235 } 205 }
236} 206}
237 207
208fn configure_radio(radio: &mut SubGhz<'_, NoDma, NoDma>, config: SubGhzRadioConfig) -> Result<(), RadioError> {
209 trace!("Configuring STM32WL SUBGHZ radio");
210
211 radio.set_regulator_mode(config.reg_mode)?;
212 radio.set_standby(StandbyClk::Rc)?;
213
214 let tcxo_mode = TcxoMode::new()
215 .set_txco_trim(TcxoTrim::Volts1pt7)
216 .set_timeout(Timeout::from_duration_sat(core::time::Duration::from_millis(100)));
217 radio.set_tcxo_mode(&tcxo_mode)?;
218 // Reduce input capacitance as shown in Reference Manual "Figure 23. HSE32 TCXO control".
219 // The STM32CUBE C driver also does this.
220 radio.set_hse_in_trim(HseTrim::MIN)?;
221
222 // Re-calibrate everything after setting the TXCO config.
223 radio.calibrate(0x7F)?;
224 radio.calibrate_image(config.calibrate_image)?;
225
226 radio.set_pa_config(&PaConfig::HP_14)?;
227 radio.set_tx_params(&TxParams::HP.set_ramp_time(RampTime::Micros40))?;
228 radio.set_pa_ocp(Ocp::Max140m)?;
229
230 radio.set_packet_type(PacketType::LoRa)?;
231 radio.set_lora_sync_word(LoRaSyncWord::Public)?;
232
233 trace!("Done initializing STM32WL SUBGHZ radio");
234 Ok(())
235}
236
238impl<RS: RadioSwitch> PhyRxTx for SubGhzRadio<'static, RS> { 237impl<RS: RadioSwitch> PhyRxTx for SubGhzRadio<'static, RS> {
239 type PhyError = RadioError; 238 type PhyError = RadioError;
240 239