use embassy_time::{Duration, Timer};
use embedded_hal::digital::OutputPin;
use embedded_hal_async::spi::SpiBus;
use crate::{cmd::cmd_regmem::write_reg_mem_mask32_cmd, constants::*};
pub use super::cmd::cmd_common::*;
use super::{BusyPin, Lr2021, Lr2021Error};
#[derive(Clone, Copy)]
pub enum PaLfOcpThr {
Default = 55, Low900Mhz = 41,
}
impl<O,SPI, M> Lr2021<O,SPI, M> where
O: OutputPin, SPI: SpiBus<u8>, M: BusyPin
{
pub async fn set_rf(&mut self, freq: u32) -> Result<(), Lr2021Error> {
let req = set_rf_frequency_cmd(freq);
self.cmd_wr(&req).await
}
pub async fn set_rf_ranging(&mut self, freq: u32) -> Result<(), Lr2021Error> {
self.set_rf(freq).await?;
self.wr_reg_mask(ADDR_FREQ_RF, 0x7F, 0).await
}
pub async fn set_rx_path(&mut self, rx_path: RxPath, rx_boost: RxBoost) -> Result<(), Lr2021Error> {
let req = set_rx_path_adv_cmd(rx_path, rx_boost);
self.cmd_wr(&req).await
}
pub async fn set_packet_type(&mut self, packet_type: PacketType) -> Result<(), Lr2021Error> {
let req = set_packet_type_cmd(packet_type);
self.cmd_wr(&req).await
}
pub async fn set_tx_params(&mut self, tx_power: i8, ramp_time: RampTime) -> Result<(), Lr2021Error> {
let req = set_tx_params_cmd(tx_power, ramp_time);
self.cmd_wr(&req).await
}
pub async fn set_pa_lf(&mut self, pa_lf_mode: PaLfMode, pa_lf_duty_cycle: u8, pa_lf_slices: u8) -> Result<(), Lr2021Error> {
let req = set_pa_config_cmd(PaSel::LfPa, pa_lf_mode, pa_lf_duty_cycle, pa_lf_slices);
self.cmd_wr(&req).await
}
pub async fn set_pa_lf_ocp_threshold(&mut self, thr: PaLfOcpThr) -> Result<(), Lr2021Error> {
let value = (thr as u32) << 19;
self.wr_reg(ADDR_PA_LOCK, 0xC0DE).await?;
self.wr_reg_mask(ADDR_PA_CTRL, 0x1F80000, value).await?;
self.wr_reg(ADDR_PA_LOCK, 0).await?;
self.wr_reg_mask(ADDR_OCP_RETENTION, 0xFF, value).await
}
pub async fn set_pa_hf(&mut self) -> Result<(), Lr2021Error> {
let req = set_pa_config_cmd(PaSel::HfPa, PaLfMode::LfPaFsm, 6, 7);
self.cmd_wr(&req).await
}
pub async fn set_fallback(&mut self, fallback_mode: FallbackMode) -> Result<(), Lr2021Error> {
let req = set_rx_tx_fallback_mode_cmd(fallback_mode);
self.cmd_wr(&req).await
}
pub async fn set_tx(&mut self, tx_timeout: u32) -> Result<(), Lr2021Error> {
let req = set_tx_adv_cmd(tx_timeout);
self.cmd_wr(&req).await
}
pub async fn set_tx_test(&mut self, mode: TestMode) -> Result<(), Lr2021Error> {
let req = set_tx_test_mode_cmd(mode);
self.cmd_wr(&req).await
}
pub async fn set_rx(&mut self, rx_timeout: u32, wait_ready: bool) -> Result<(), Lr2021Error> {
let req = set_rx_adv_cmd(rx_timeout);
self.cmd_wr(&req).await?;
if wait_ready {
self.wait_ready(Duration::from_millis(100)).await?;
}
Ok(())
}
pub async fn set_rx_continous(&mut self) -> Result<(), Lr2021Error> {
self.set_rx(0xFFFFFF,true).await
}
pub async fn set_rx_duty_cycle(&mut self, listen_time: u32, cycle_time: u32, use_lora_cad: bool, dram_ret: u8) -> Result<(), Lr2021Error> {
let req = set_rx_duty_cycle_cmd(listen_time, cycle_time, use_lora_cad, dram_ret);
self.cmd_wr(&req).await
}
pub async fn set_auto_rxtx(&mut self, clear: bool, mode: AutoTxrxMode, timeout: u32, delay: u32) -> Result<(), Lr2021Error> {
let req = set_auto_rx_tx_cmd(clear, mode, timeout, delay);
self.cmd_wr(&req).await
}
pub async fn set_cad_params(&mut self, cad_timeout: u32, threshold: u8, exit_mode: ExitMode, trx_timeout: u32) -> Result<(), Lr2021Error> {
let req = set_cad_params_cmd(cad_timeout, threshold, exit_mode, trx_timeout);
self.cmd_wr(&req).await
}
pub async fn set_cad(&mut self) -> Result<(), Lr2021Error> {
self.cmd_wr(&set_cad_cmd()).await
}
pub async fn set_cca(&mut self, duration: u32, gain: Option<u8>) -> Result<(), Lr2021Error> {
let req = set_cca_adv_cmd(duration, gain.unwrap_or(0));
let len = req.len() - if gain.is_none() {1} else {0};
self.cmd_wr(&req[..len]).await
}
pub async fn get_cca_result(&mut self) -> Result<CcaResultRsp, Lr2021Error> {
let req = get_cca_result_req();
let mut rsp = CcaResultRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp)
}
pub async fn set_and_get_cca(&mut self, duration: u32, gain: Option<u8>) -> Result<CcaResultRsp, Lr2021Error> {
let req = set_cca_adv_cmd(duration, gain.unwrap_or(0));
let len = req.len() - if gain.is_none() {1} else {0};
self.cmd_wr(&req[..len]).await?;
let dur_ns = (duration as u64 ) << 5;
Timer::after_nanos(dur_ns).await;
self.get_cca_result().await
}
pub async fn set_rx_gain(&mut self, gain: u8) -> Result<(), Lr2021Error> {
let req = set_agc_gain_manual_cmd(gain.min(13));
self.cmd_wr(&req).await
}
pub async fn clear_rx_stats(&mut self) -> Result<(), Lr2021Error> {
self.cmd_wr(&reset_rx_stats_cmd()).await
}
pub async fn get_rx_pkt_len(&mut self) -> Result<u16, Lr2021Error> {
let req = get_rx_pkt_length_req();
let mut rsp = RxPktLengthRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp.pkt_length())
}
pub async fn force_crc_out(&mut self) -> Result<(), Lr2021Error> {
let req = write_reg_mem_mask32_cmd(0xF30844, 0x01000000, 0);
self.cmd_wr(&req).await
}
pub async fn get_rssi_inst(&mut self) -> Result<u16, Lr2021Error> {
let req = get_rssi_inst_req();
let mut rsp = RssiInstRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp.rssi())
}
pub async fn get_rssi_avg(&mut self, nb_meas: u16) -> Result<u16, Lr2021Error> {
let mut rssi = 0;
for _ in 0..nb_meas {
rssi += self.get_rssi_inst().await?;
}
Ok((rssi + (nb_meas>>1)) / nb_meas)
}
pub async fn set_default_timeout(&mut self, tx: u32, rx: u32) -> Result<(), Lr2021Error> {
let req = set_default_rx_tx_timeout_cmd(rx, tx);
self.cmd_wr(&req).await
}
pub async fn set_stop_timeout(&mut self, on_preamble: bool) -> Result<(), Lr2021Error> {
let req = set_stop_timeout_cmd(on_preamble);
self.cmd_wr(&req).await
}
pub async fn set_timestamp_source(&mut self, index: TimestampIndex, source: TimestampSource) -> Result<(), Lr2021Error> {
let req = set_timestamp_source_cmd(index, source);
self.cmd_wr(&req).await
}
pub async fn get_timestamp(&mut self, index: TimestampIndex) -> Result<u32, Lr2021Error> {
let req = get_timestamp_value_req(index);
let mut rsp = TimestampValueRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp.timestamp())
}
}