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::interrupt::{Interrupt, InterruptExt, SUBGHZ_RADIO};
|
||||
use embassy_stm32::subghz::{
|
||||
CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, Irq, LoRaBandwidth, LoRaModParams, LoRaPacketParams,
|
||||
LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk,
|
||||
Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
|
||||
CalibrateImage, CfgIrq, CodingRate, Error, HeaderType, HseTrim, Irq, LoRaBandwidth, LoRaModParams,
|
||||
LoRaPacketParams, LoRaSyncWord, Ocp, PaConfig, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF,
|
||||
StandbyClk, Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
|
||||
};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
@ -61,46 +61,17 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
||||
unsafe { SUBGHZ_RADIO::steal().disable() };
|
||||
});
|
||||
|
||||
Self { radio, switch, irq }
|
||||
}
|
||||
configure_radio(&mut radio, config)?;
|
||||
|
||||
/// Configure radio settings in preparation for TX or RX
|
||||
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(())
|
||||
Ok(Self { radio, switch, irq })
|
||||
}
|
||||
|
||||
/// Perform a transmission with the given parameters and payload. Returns any time adjustements needed form
|
||||
/// the upcoming RX window start.
|
||||
async fn do_tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, RadioError> {
|
||||
//trace!("TX Request: {}", config);
|
||||
trace!("TX START");
|
||||
trace!("TX Request: {}", config);
|
||||
//trace!("TX START");
|
||||
self.switch.set_tx();
|
||||
self.configure()?;
|
||||
|
||||
self.radio
|
||||
.set_rf_frequency(&RfFreq::from_frequency(config.rf.frequency))?;
|
||||
@ -164,7 +135,6 @@ impl<'d, RS: RadioSwitch> SubGhzRadio<'d, RS> {
|
||||
trace!("RX START");
|
||||
// trace!("Starting RX: {}", config);
|
||||
self.switch.set_rx();
|
||||
self.configure()?;
|
||||
|
||||
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()
|
||||
.irq_enable_all(Irq::RxDone)
|
||||
.irq_enable_all(Irq::PreambleDetected)
|
||||
//.irq_enable_all(Irq::PreambleDetected)
|
||||
.irq_enable_all(Irq::HeaderErr)
|
||||
.irq_enable_all(Irq::Timeout)
|
||||
.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> {
|
||||
type PhyError = RadioError;
|
||||
|
||||
|
@ -60,7 +60,9 @@ async fn main(_spawner: Spawner) {
|
||||
let radio = SubGhz::new(p.SUBGHZSPI, NoDma, NoDma);
|
||||
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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user