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.
This commit is contained in:
parent
69d80c086d
commit
f31116cafa
@ -6,9 +6,9 @@ use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
|||||||
use embassy_stm32::dma::NoDma;
|
use embassy_stm32::dma::NoDma;
|
||||||
use embassy_stm32::interrupt::{Interrupt, InterruptExt, SUBGHZ_RADIO};
|
use embassy_stm32::interrupt::{Interrupt, InterruptExt, SUBGHZ_RADIO};
|
||||||
use embassy_stm32::subghz::{
|
use embassy_stm32::subghz::{
|
||||||
CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, Irq, LoRaBandwidth, LoRaModParams, LoRaPacketParams,
|
CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, HseTrim, Irq, LoRaBandwidth, LoRaModParams,
|
||||||
LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk,
|
LoRaPacketParams, LoRaSyncWord, Ocp, PaConfig, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF,
|
||||||
Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
|
StandbyClk, Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
|
||||||
};
|
};
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
@ -61,46 +61,17 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
|||||||
unsafe { SUBGHZ_RADIO::steal().disable() };
|
unsafe { SUBGHZ_RADIO::steal().disable() };
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { radio, switch, irq }
|
configure_radio(&mut radio, config)?;
|
||||||
}
|
|
||||||
|
|
||||||
/// Configure radio settings in preparation for TX or RX
|
Ok(Self { radio, switch, irq })
|
||||||
pub(crate) fn configure(&mut self) -> Result<(), RadioError> {
|
|
||||||
trace!("Configuring STM32WL SUBGHZ radio");
|
|
||||||
self.radio.set_standby(StandbyClk::Rc)?;
|
|
||||||
let tcxo_mode = TcxoMode::new()
|
|
||||||
.set_txco_trim(TcxoTrim::Volts1pt7)
|
|
||||||
.set_timeout(Timeout::from_duration_sat(core::time::Duration::from_millis(40)));
|
|
||||||
|
|
||||||
self.radio.set_tcxo_mode(&tcxo_mode)?;
|
|
||||||
self.radio.set_regulator_mode(RegMode::Ldo)?;
|
|
||||||
|
|
||||||
self.radio.calibrate_image(CalibrateImage::ISM_863_870)?;
|
|
||||||
|
|
||||||
self.radio.set_buffer_base_address(0, 0)?;
|
|
||||||
|
|
||||||
self.radio
|
|
||||||
.set_pa_config(&PaConfig::new().set_pa_duty_cycle(0x1).set_hp_max(0x0).set_pa(PaSel::Lp))?;
|
|
||||||
|
|
||||||
self.radio.set_pa_ocp(Ocp::Max140m)?;
|
|
||||||
|
|
||||||
// let tx_params = TxParams::LP_14.set_ramp_time(RampTime::Micros40);
|
|
||||||
self.radio
|
|
||||||
.set_tx_params(&TxParams::new().set_ramp_time(RampTime::Micros40).set_power(0x0A))?;
|
|
||||||
|
|
||||||
self.radio.set_packet_type(PacketType::LoRa)?;
|
|
||||||
self.radio.set_lora_sync_word(LoRaSyncWord::Public)?;
|
|
||||||
trace!("Done initializing STM32WL SUBGHZ radio");
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a transmission with the given parameters and payload. Returns any time adjustements needed form
|
/// Perform a transmission with the given parameters and payload. Returns any time adjustements needed form
|
||||||
/// the upcoming RX window start.
|
/// the upcoming RX window start.
|
||||||
async fn do_tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, RadioError> {
|
async fn do_tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, RadioError> {
|
||||||
//trace!("TX Request: {}", config);
|
trace!("TX Request: {}", config);
|
||||||
trace!("TX START");
|
//trace!("TX START");
|
||||||
self.switch.set_tx();
|
self.switch.set_tx();
|
||||||
self.configure()?;
|
|
||||||
|
|
||||||
self.radio
|
self.radio
|
||||||
.set_rf_frequency(&RfFreq::from_frequency(config.rf.frequency))?;
|
.set_rf_frequency(&RfFreq::from_frequency(config.rf.frequency))?;
|
||||||
@ -164,7 +135,6 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
|||||||
trace!("RX START");
|
trace!("RX START");
|
||||||
// trace!("Starting RX: {}", config);
|
// trace!("Starting RX: {}", config);
|
||||||
self.switch.set_rx();
|
self.switch.set_rx();
|
||||||
self.configure()?;
|
|
||||||
|
|
||||||
self.radio.set_rf_frequency(&RfFreq::from_frequency(config.frequency))?;
|
self.radio.set_rf_frequency(&RfFreq::from_frequency(config.frequency))?;
|
||||||
|
|
||||||
@ -180,7 +150,7 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
|||||||
|
|
||||||
let irq_cfg = CfgIrq::new()
|
let irq_cfg = CfgIrq::new()
|
||||||
.irq_enable_all(Irq::RxDone)
|
.irq_enable_all(Irq::RxDone)
|
||||||
.irq_enable_all(Irq::PreambleDetected)
|
//.irq_enable_all(Irq::PreambleDetected)
|
||||||
.irq_enable_all(Irq::HeaderErr)
|
.irq_enable_all(Irq::HeaderErr)
|
||||||
.irq_enable_all(Irq::Timeout)
|
.irq_enable_all(Irq::Timeout)
|
||||||
.irq_enable_all(Irq::Err);
|
.irq_enable_all(Irq::Err);
|
||||||
@ -235,6 +205,35 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn configure_radio(radio: &mut SubGhz<'_, NoDma, NoDma>, config: SubGhzRadioConfig) -> Result<(), RadioError> {
|
||||||
|
trace!("Configuring STM32WL SUBGHZ radio");
|
||||||
|
|
||||||
|
radio.set_regulator_mode(config.reg_mode)?;
|
||||||
|
radio.set_standby(StandbyClk::Rc)?;
|
||||||
|
|
||||||
|
let tcxo_mode = TcxoMode::new()
|
||||||
|
.set_txco_trim(TcxoTrim::Volts1pt7)
|
||||||
|
.set_timeout(Timeout::from_duration_sat(core::time::Duration::from_millis(100)));
|
||||||
|
radio.set_tcxo_mode(&tcxo_mode)?;
|
||||||
|
// Reduce input capacitance as shown in Reference Manual "Figure 23. HSE32 TCXO control".
|
||||||
|
// The STM32CUBE C driver also does this.
|
||||||
|
radio.set_hse_in_trim(HseTrim::MIN)?;
|
||||||
|
|
||||||
|
// Re-calibrate everything after setting the TXCO config.
|
||||||
|
radio.calibrate(0x7F)?;
|
||||||
|
radio.calibrate_image(config.calibrate_image)?;
|
||||||
|
|
||||||
|
radio.set_pa_config(&PaConfig::HP_14)?;
|
||||||
|
radio.set_tx_params(&TxParams::HP.set_ramp_time(RampTime::Micros40))?;
|
||||||
|
radio.set_pa_ocp(Ocp::Max140m)?;
|
||||||
|
|
||||||
|
radio.set_packet_type(PacketType::LoRa)?;
|
||||||
|
radio.set_lora_sync_word(LoRaSyncWord::Public)?;
|
||||||
|
|
||||||
|
trace!("Done initializing STM32WL SUBGHZ radio");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
impl<RS: RadioSwitch> PhyRxTx for SubGhzRadio<'static, RS> {
|
impl<RS: RadioSwitch> PhyRxTx for SubGhzRadio<'static, RS> {
|
||||||
type PhyError = RadioError;
|
type PhyError = RadioError;
|
||||||
|
|
||||||
|
@ -60,7 +60,9 @@ async fn main(_spawner: Spawner) {
|
|||||||
let radio = SubGhz::new(p.SUBGHZSPI, NoDma, NoDma);
|
let radio = SubGhz::new(p.SUBGHZSPI, NoDma, NoDma);
|
||||||
let irq = interrupt::take!(SUBGHZ_RADIO);
|
let irq = interrupt::take!(SUBGHZ_RADIO);
|
||||||
|
|
||||||
let radio = SubGhzRadio::new(radio, rfs, irq);
|
let mut radio_config = SubGhzRadioConfig::default();
|
||||||
|
radio_config.calibrate_image = CalibrateImage::ISM_863_870;
|
||||||
|
let radio = SubGhzRadio::new(radio, rfs, irq, radio_config).unwrap();
|
||||||
|
|
||||||
let mut region: region::Configuration = region::EU868::default().into();
|
let mut region: region::Configuration = region::EU868::default().into();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user