Improve generics and consolidate antenna handling

This commit is contained in:
ceekdee 2022-10-08 14:32:22 -05:00
parent bb84d7a0ae
commit f554962f54
6 changed files with 69 additions and 87 deletions

View File

@ -13,35 +13,29 @@ use sx126x_lora::LoRa;
use self::sx126x_lora::mod_params::RadioError; use self::sx126x_lora::mod_params::RadioError;
/// Semtech Sx126x LoRa peripheral /// Semtech Sx126x LoRa peripheral
pub struct Sx126xRadio<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> pub struct Sx126xRadio<SPI, CTRL, WAIT, BUS>
where where
SPI: SpiBus<u8, Error = BUS> + 'static, SPI: SpiBus<u8, Error = BUS> + 'static,
CS: OutputPin + 'static, CTRL: OutputPin + 'static,
RESET: OutputPin + 'static,
ANTRX: OutputPin + 'static,
ANTTX: OutputPin + 'static,
WAIT: Wait + 'static, WAIT: Wait + 'static,
BUS: Error + Format + 'static, BUS: Error + Format + 'static,
{ {
pub lora: LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT>, pub lora: LoRa<SPI, CTRL, WAIT>,
} }
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> Sx126xRadio<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> impl<SPI, CTRL, WAIT, BUS> Sx126xRadio<SPI, CTRL, WAIT, BUS>
where where
SPI: SpiBus<u8, Error = BUS> + 'static, SPI: SpiBus<u8, Error = BUS> + 'static,
CS: OutputPin + 'static, CTRL: OutputPin + 'static,
RESET: OutputPin + 'static,
ANTRX: OutputPin + 'static,
ANTTX: OutputPin + 'static,
WAIT: Wait + 'static, WAIT: Wait + 'static,
BUS: Error + Format + 'static, BUS: Error + Format + 'static,
{ {
pub async fn new( pub async fn new(
spi: SPI, spi: SPI,
cs: CS, cs: CTRL,
reset: RESET, reset: CTRL,
antenna_rx: ANTRX, antenna_rx: CTRL,
antenna_tx: ANTTX, antenna_tx: CTRL,
dio1: WAIT, dio1: WAIT,
busy: WAIT, busy: WAIT,
enable_public_network: bool, enable_public_network: bool,
@ -53,13 +47,10 @@ where
} }
} }
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> Timings for Sx126xRadio<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> impl<SPI, CTRL, WAIT, BUS> Timings for Sx126xRadio<SPI, CTRL, WAIT, BUS>
where where
SPI: SpiBus<u8, Error = BUS> + 'static, SPI: SpiBus<u8, Error = BUS> + 'static,
CS: OutputPin + 'static, CTRL: OutputPin + 'static,
RESET: OutputPin + 'static,
ANTRX: OutputPin + 'static,
ANTTX: OutputPin + 'static,
WAIT: Wait + 'static, WAIT: Wait + 'static,
BUS: Error + Format + 'static, BUS: Error + Format + 'static,
{ {
@ -71,13 +62,10 @@ where
} }
} }
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> PhyRxTx for Sx126xRadio<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> impl<SPI, CTRL, WAIT, BUS> PhyRxTx for Sx126xRadio<SPI, CTRL, WAIT, BUS>
where where
SPI: SpiBus<u8, Error = BUS> + 'static, SPI: SpiBus<u8, Error = BUS> + 'static,
CS: OutputPin + 'static, CTRL: OutputPin + 'static,
RESET: OutputPin + 'static,
ANTRX: OutputPin + 'static,
ANTTX: OutputPin + 'static,
WAIT: Wait + 'static, WAIT: Wait + 'static,
BUS: Error + Format + 'static, BUS: Error + Format + 'static,
{ {
@ -86,10 +74,7 @@ where
type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm
where where
SPI: 'm, SPI: 'm,
CS: 'm, CTRL: 'm,
RESET: 'm,
ANTRX: 'm,
ANTTX: 'm,
WAIT: 'm, WAIT: 'm,
BUS: 'm; BUS: 'm;
@ -122,10 +107,7 @@ where
type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm
where where
SPI: 'm, SPI: 'm,
CS: 'm, CTRL: 'm,
RESET: 'm,
ANTRX: 'm,
ANTTX: 'm,
WAIT: 'm, WAIT: 'm,
BUS: 'm; BUS: 'm;

View File

@ -13,13 +13,10 @@ const BRD_TCXO_WAKEUP_TIME: u32 = 10;
// Provides board-specific functionality for Semtech SX126x-based boards. Use #[cfg(feature = "board_type")] to specify unique board functionality. // Provides board-specific functionality for Semtech SX126x-based boards. Use #[cfg(feature = "board_type")] to specify unique board functionality.
// The base implementation supports the RAK4631 board. // The base implementation supports the RAK4631 board.
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT> impl<SPI, CTRL, WAIT, BUS> LoRa<SPI, CTRL, WAIT>
where where
SPI: SpiBus<u8, Error = BUS>, SPI: SpiBus<u8, Error = BUS>,
CS: OutputPin, CTRL: OutputPin,
RESET: OutputPin,
ANTRX: OutputPin,
ANTTX: OutputPin,
WAIT: Wait, WAIT: Wait,
{ {
// De-initialize the radio I/Os pins interface. Useful when going into MCU low power modes. // De-initialize the radio I/Os pins interface. Useful when going into MCU low power modes.
@ -210,14 +207,34 @@ where
RadioType::SX1262 RadioType::SX1262
} }
// Initialize the RF switch I/O pins interface // Quiesce the antenna(s).
pub(super) async fn brd_ant_sw_on(&mut self) -> Result<(), RadioError<BUS>> { pub(super) fn brd_ant_sleep(&mut self) -> Result<(), RadioError<BUS>> {
Ok(()) // no operation currently #[cfg(feature = "rak4631")]
{
self.antenna_tx.set_low().map_err(|_| AntTx)?;
self.antenna_rx.set_low().map_err(|_| AntRx)?;
}
Ok(())
} }
// De-initialize the RF switch I/O pins interface for MCU low power modes // Prepare the antenna(s) for a receive operation
pub(super) async fn brd_ant_sw_off(&mut self) -> Result<(), RadioError<BUS>> { pub(super) fn brd_ant_set_rx(&mut self) -> Result<(), RadioError<BUS>> {
Ok(()) // no operation currently #[cfg(feature = "rak4631")]
{
self.antenna_tx.set_low().map_err(|_| AntTx)?;
self.antenna_rx.set_high().map_err(|_| AntRx)?;
}
Ok(())
}
// Prepare the antenna(s) for a send operation
pub(super) fn brd_ant_set_tx(&mut self) -> Result<(), RadioError<BUS>> {
#[cfg(feature = "rak4631")]
{
self.antenna_rx.set_low().map_err(|_| AntRx)?;
self.antenna_tx.set_high().map_err(|_| AntTx)?;
}
Ok(())
} }
// Check if the given RF frequency is supported by the hardware // Check if the given RF frequency is supported by the hardware

View File

@ -26,12 +26,12 @@ const LORA_BANDWIDTHS: [Bandwidth; 3] = [Bandwidth::_125KHz, Bandwidth::_250KHz,
const RADIO_WAKEUP_TIME: u32 = 3; const RADIO_WAKEUP_TIME: u32 = 3;
/// Provides high-level access to Semtech SX126x-based boards /// Provides high-level access to Semtech SX126x-based boards
pub struct LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT> { pub struct LoRa<SPI, CTRL, WAIT> {
spi: SPI, spi: SPI,
cs: CS, cs: CTRL,
reset: RESET, reset: CTRL,
antenna_rx: ANTRX, antenna_rx: CTRL,
antenna_tx: ANTTX, antenna_tx: CTRL,
dio1: WAIT, dio1: WAIT,
busy: WAIT, busy: WAIT,
operating_mode: RadioMode, operating_mode: RadioMode,
@ -45,17 +45,14 @@ pub struct LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT> {
frequency_error: u32, frequency_error: u32,
} }
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT> impl<SPI, CTRL, WAIT, BUS> LoRa<SPI, CTRL, WAIT>
where where
SPI: SpiBus<u8, Error = BUS>, SPI: SpiBus<u8, Error = BUS>,
CS: OutputPin, CTRL: OutputPin,
RESET: OutputPin,
ANTRX: OutputPin,
ANTTX: OutputPin,
WAIT: Wait, WAIT: Wait,
{ {
/// Builds and returns a new instance of the radio. Only one instance of the radio should exist at a time () /// Builds and returns a new instance of the radio. Only one instance of the radio should exist at a time ()
pub fn new(spi: SPI, cs: CS, reset: RESET, antenna_rx: ANTRX, antenna_tx: ANTTX, dio1: WAIT, busy: WAIT) -> Self { pub fn new(spi: SPI, cs: CTRL, reset: CTRL, antenna_rx: CTRL, antenna_tx: CTRL, dio1: WAIT, busy: WAIT) -> Self {
Self { Self {
spi, spi,
cs, cs,

View File

@ -19,13 +19,10 @@ const SX126X_MAX_LORA_SYMB_NUM_TIMEOUT: u8 = 248;
// Provides board-specific functionality for Semtech SX126x-based boards // Provides board-specific functionality for Semtech SX126x-based boards
impl<SPI, CS, RESET, ANTRX, ANTTX, WAIT, BUS> LoRa<SPI, CS, RESET, ANTRX, ANTTX, WAIT> impl<SPI, CTRL, WAIT, BUS> LoRa<SPI, CTRL, WAIT>
where where
SPI: SpiBus<u8, Error = BUS>, SPI: SpiBus<u8, Error = BUS>,
CS: OutputPin, CTRL: OutputPin,
RESET: OutputPin,
ANTRX: OutputPin,
ANTTX: OutputPin,
WAIT: Wait, WAIT: Wait,
{ {
// Initialize the radio driver // Initialize the radio driver
@ -44,7 +41,6 @@ where
let operating_mode = self.brd_get_operating_mode(); let operating_mode = self.brd_get_operating_mode();
if operating_mode == RadioMode::Sleep || operating_mode == RadioMode::ReceiveDutyCycle { if operating_mode == RadioMode::Sleep || operating_mode == RadioMode::ReceiveDutyCycle {
self.brd_wakeup().await?; self.brd_wakeup().await?;
self.brd_ant_sw_on().await?;
} }
self.brd_wait_on_busy().await?; self.brd_wait_on_busy().await?;
Ok(()) Ok(())
@ -117,10 +113,7 @@ where
// Set the radio in sleep mode // Set the radio in sleep mode
pub(super) async fn sub_set_sleep(&mut self, sleep_config: SleepParams) -> Result<(), RadioError<BUS>> { pub(super) async fn sub_set_sleep(&mut self, sleep_config: SleepParams) -> Result<(), RadioError<BUS>> {
self.brd_ant_sw_off().await?; self.brd_ant_sleep()?;
let _fix_rx = self.antenna_rx.set_low();
let _fix_tx = self.antenna_tx.set_low();
if !sleep_config.warm_start { if !sleep_config.warm_start {
self.image_calibrated = false; self.image_calibrated = false;
@ -141,8 +134,7 @@ where
self.brd_set_operating_mode(RadioMode::StandbyXOSC); self.brd_set_operating_mode(RadioMode::StandbyXOSC);
} }
let _fix_rx = self.antenna_rx.set_low(); self.brd_ant_sleep()?;
let _fix_tx = self.antenna_tx.set_low();
Ok(()) Ok(())
} }
@ -162,8 +154,7 @@ where
Self::timeout_3(timeout), Self::timeout_3(timeout),
]; ];
let _fix_rx = self.antenna_rx.set_low(); self.brd_ant_set_tx()?;
let _fix_tx = self.antenna_tx.set_high();
self.brd_set_operating_mode(RadioMode::Transmit); self.brd_set_operating_mode(RadioMode::Transmit);
self.brd_write_command(OpCode::SetTx, &buffer).await?; self.brd_write_command(OpCode::SetTx, &buffer).await?;
@ -178,8 +169,7 @@ where
Self::timeout_3(timeout), Self::timeout_3(timeout),
]; ];
let _fix_rx = self.antenna_rx.set_high(); self.brd_ant_set_rx()?;
let _fix_tx = self.antenna_tx.set_low();
self.brd_set_operating_mode(RadioMode::Receive); self.brd_set_operating_mode(RadioMode::Receive);
self.brd_write_registers(Register::RxGain, &[0x94u8]).await?; self.brd_write_registers(Register::RxGain, &[0x94u8]).await?;
@ -195,8 +185,7 @@ where
Self::timeout_3(timeout), Self::timeout_3(timeout),
]; ];
let _fix_rx = self.antenna_rx.set_high(); self.brd_ant_set_rx()?;
let _fix_tx = self.antenna_tx.set_low();
self.brd_set_operating_mode(RadioMode::Receive); self.brd_set_operating_mode(RadioMode::Receive);
// set max LNA gain, increase current by ~2mA for around ~3dB in sensitivity // set max LNA gain, increase current by ~2mA for around ~3dB in sensitivity
@ -225,8 +214,7 @@ where
// Set the radio in CAD mode // Set the radio in CAD mode
pub(super) async fn sub_set_cad(&mut self) -> Result<(), RadioError<BUS>> { pub(super) async fn sub_set_cad(&mut self) -> Result<(), RadioError<BUS>> {
let _fix_rx = self.antenna_rx.set_high(); self.brd_ant_set_rx()?;
let _fix_tx = self.antenna_tx.set_low();
self.brd_write_command(OpCode::SetCAD, &[]).await?; self.brd_write_command(OpCode::SetCAD, &[]).await?;
self.brd_set_operating_mode(RadioMode::ChannelActivityDetection); self.brd_set_operating_mode(RadioMode::ChannelActivityDetection);
@ -235,8 +223,7 @@ where
// Set the radio in continuous wave transmission mode // Set the radio in continuous wave transmission mode
pub(super) async fn sub_set_tx_continuous_wave(&mut self) -> Result<(), RadioError<BUS>> { pub(super) async fn sub_set_tx_continuous_wave(&mut self) -> Result<(), RadioError<BUS>> {
let _fix_rx = self.antenna_rx.set_low(); self.brd_ant_set_tx()?;
let _fix_tx = self.antenna_tx.set_high();
self.brd_write_command(OpCode::SetTxContinuousWave, &[]).await?; self.brd_write_command(OpCode::SetTxContinuousWave, &[]).await?;
self.brd_set_operating_mode(RadioMode::Transmit); self.brd_set_operating_mode(RadioMode::Transmit);
@ -245,8 +232,7 @@ where
// Set the radio in continuous preamble transmission mode // Set the radio in continuous preamble transmission mode
pub(super) async fn sub_set_tx_infinite_preamble(&mut self) -> Result<(), RadioError<BUS>> { pub(super) async fn sub_set_tx_infinite_preamble(&mut self) -> Result<(), RadioError<BUS>> {
let _fix_rx = self.antenna_rx.set_low(); self.brd_ant_set_tx()?;
let _fix_tx = self.antenna_tx.set_high();
self.brd_write_command(OpCode::SetTxContinuousPremable, &[]).await?; self.brd_write_command(OpCode::SetTxContinuousPremable, &[]).await?;
self.brd_set_operating_mode(RadioMode::Transmit); self.brd_set_operating_mode(RadioMode::Transmit);

View File

@ -24,12 +24,12 @@ async fn main(_spawner: Spawner) {
let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); let dio1 = Input::new(p.P1_15.degrade(), Pull::Down);
let busy = Input::new(p.P1_14.degrade(), Pull::Down); let busy = Input::new(p.P1_14.degrade(), Pull::Down);
let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard);
let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard);
match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await {
Ok(r) => r, Ok(r) => r,

View File

@ -97,12 +97,12 @@ async fn main(spawner: Spawner) {
let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); let dio1 = Input::new(p.P1_15.degrade(), Pull::Down);
let busy = Input::new(p.P1_14.degrade(), Pull::Down); let busy = Input::new(p.P1_14.degrade(), Pull::Down);
let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard);
let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard);
match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await {
Ok(r) => r, Ok(r) => r,